您的位置:首页 > 编程语言

LeetCode代码分析——4. Median of Two Sorted Arrays

2016-04-14 15:37 435 查看
一道找中间数的题,两个排序好的数组

最简单粗暴的方法很容易,就是搞个排序(归并分治策略的最后一步合并两个排序好的数组?or快排?),然后找到(m+n)/2位置的数

下面这种思想认为找中间数就是找第k = (m+n)/2大的数,找两个数组合起来后第k大的数,分别看A数组和B数组中间(k/2)位置的数,小的数的左半部分可以抛弃,然后剩下的再找。。。直到第一个数组被掏空(就直接找第二个的k位置,注意只可能是第一个数组被掏空,因为第一个数组一定比第二个数组短,如果不是的话A,B是会互换的),或者前面的部分已经被抛弃完只能找第一个(比较A和B的第一个),或者发现A和B的中点相等(那就直接返回这个相等的数)

public class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int m = nums1.length;
int n = nums2.length;
int size = m + n;
if(size % 2 == 1){
return findKth(nums1, 0, m, nums2, 0, n, size/2 + 1);
} else{
return (findKth(nums1, 0, m, nums2, 0, n, size/2) + findKth(nums1, 0, m, nums2, 0, n, size/2 + 1)) / 2;
}
}

public double findKth(int[] nums1,int s1, int m, int[] nums2,int s2, int n, int k){
//假定nums1永远比nums2短
if(m > n){
return findKth(nums2, s2 , n, nums1, s1, m, k);
}
else if(m == 0){
return nums2[s2 + k - 1];
}
else if(k == 1){
return nums1[s1] < nums2[s2] ? nums1[s1] : nums2[s2];
}
//A = {1,3,5} B = {2,4,6,8} 共7个,找第四个,找A里面的第二个,B里面的第二个,
//3 < 4,(反证)假设3是整个里面第五个,那么A里面最多一个比3小,B里面最多1个比3小,才两个,根本不够凑足4个
//所以3一定是在第四个之前,所以可以抛弃掉3和它之前的部分
int pa = k/2 < m? k/2 : m;
int pb = k - pa;
//如果A的第pa个数小,那么抛弃掉A前面那些,B不变,这样就少了前pa个,
//找k-pa个(找第三名,前两名死了,想找第三名就成了找剩下人里的第一名了)
if(nums1[s1 + pa - 1] < nums2[s2 + pb - 1]){
return findKth(nums1, s1 + pa, m - pa, nums2, s2, n, k - pa);
}
else if(nums1[s1 + pa - 1] > nums2[s2 + pb - 1]){
return findKth(nums1, s1, m, nums2, s2 + pb, n - pb, k - pb);
}
//A = {1,3,5} B = {2,3,6,8} 同上,这时A里面的第二个,B里面的第二个都是3,
//总体是{1,2,3,3,5,6,8},3可以算是在3的前面,这样3前面有1个,3前面有1个,3前面可以说有个3,
//找第四个,刚好前面有三个,刚好就是。所以相等的情况下可以直接返回
//else if(nums1[s1 + pa - 1] == nums2[s2 + pb - 1]){
else{
return nums1[s1 + pa - 1];
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: