题目
Given an increasing sequence S of N integers, the median is the number at the middle position. For example, the median of S1={11, 12, 13, 14} is 12, and the median of S2={9, 10, 15, 16, 17} is 15. The median of two sequences is defined to be the median of the nondecreasing sequence which contains all the elements of both sequences. For example, the median of S1 and S2 is 13.
Given two increasing sequences of integers, you are asked to find their median.
Input
Each input file contains one test case. Each case occupies 2 lines, each gives the information of a sequence. For each sequence, the first positive integer N (<=1000000) is the size of that sequence. Then N integers follow, separated by a space. It is guaranteed that all the integers are in the range of long int.
Output
For each test case you should output the median of the two given sequences in a line.
Sample Input
4 11 12 13 14
5 9 10 15 16 17
Sample Output
13
解析
这道题目是给定两个递增序列s1,s2,然后找出递增序列的中位数,注意一点如果两个序列总共有count个数
- count为偶数,则取第count/2个数
- count为奇数,则取第count/2+1个数
这道题更通用的问题是寻找两个递增序列中第K个数,解法有如下几种,推荐采用二分思想
常规做法1
由于两个数组已经排序,直接merge两个数组,然后取出所需元素即可。
常规解法2
由于数组已排序,且只需获得第K个元素,故使用两个整数i和j分别指向数组A和B的起始位置,整数m记录当前遍历的元素个数,if(A[i]<B[j]) i++;m++
,否则j++;m++
;当m==k时,取出元素即为所求
类二分查找求解方法
考虑到数组有序,采用类似二分查找的方法,每次从数组中删除K/2个元素。
假设A和B的元素个数都大于k/2,则将A中第k/2个元素(即A[K/2-1])和B中第K/2个元素(即B[k/2-1])进行比较,可考虑如下三种情况(假设K为偶数):
- A[K/2-1]
代码
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
double findKelement(vector<long int>& nums1, vector<long int>& nums2,int i1,int i2,int j1,int j2,int k ){
if(i1>=i2) return nums2[j1+k-1];
else if(j1>=j2) return nums1[i1+k-1];
else if(k==1) return min(nums1[i1],nums2[j1]);
long int m1=min(i2-1,i1+k/2-1),m2=min(j2-1,j1+k/2-1);
if(nums1[m1]<nums2[m2]) return findKelement(nums1,nums2,m1+1,i2,j1,j2,k-(m1-i1+1));
else return findKelement(nums1,nums2,i1,i2,m2+1,j2,k-m2+j1-1);
}
int main(){
long int n,m;
scanf("%ld",&n);
vector<long int> v1(n);
for(int i=0;i<n;i++){
scanf("%ld",&v1[i]);
}
scanf("%ld",&m);
vector<long int> v2(m);
for(int j=0;j<m;j++){
scanf("%ld",&v2[j]);
}
int count=m+n;
if(count%2==0) count=count/2;
else count=count/2+1;
long int res=findKelement(v1,v2,0,n,0,m,count);
printf("%ld\n",res);
return 0;
}