LintCode 解题记录 7.11 ~ 7.16

来源:互联网 发布:棹俊树x先导爱知 编辑:程序博客网 时间:2024/05/18 01:44

7.1~7.10号去南京玩了,所以没有刷题。现在回来了,题目继续搞起吧~

LintCode Median of Two Sorted Array

HARD题,没做出来。
看完网上的思路来总结一下:
这题可以转换为topK问题来解决,已知有序数组A和数组B,其合并后的中位数就是求其第k(k = (A.size+B.size)/2 )小数的问题。我们可以分别在数组A和B中考虑第k/2数,即A[k/2-1]和B[k/2-1],那么就可以分为三种情况:
1)A[k/2-1] < B[k/2-1],那么小于A[k/2-1]的数最多就有A[0],A[1],..A[k/2-2]和B[0],B[1],…,B[k/2-2],即k-2个数,也就是A[k/2-1]至多是k-1小的数,永远不可能是第k小的数。所以A[0],..,A[k/2-1]这些数都可以丢弃,那么原问题就变成了在新的两个有序数组中求第k/2小数。
2)A[k/2-1] > B[k/2-1],同样可以跟上面考虑。
3)如果两者相等,那么A[k/2-1]就是想要的第k小的数。
那么代码如下:

    double findMedianSortedArrays(vector<int> A, vector<int> B) {        // write your code here       int total = A.size()+B.size();       if (total % 2 == 1) {           return findKth(A, 0, B, 0, total/2+1);       } else {           return (findKth(A, 0, B, 0, total/2)+findKth(A, 0, B, 0, total/2+1))/2;       }    }    double findKth(vector<int> A, int i, vector<int> B, int j, int k) { //i和j代表数组A和B的起始位置        //首先确保A的size小于B的size,如果不是,则交换两个数组即可。        if (A.size()-i > B.size()-j) return findKth(B, j, A, i, k);        //如果A数组为空,那么就返回B数组的第k小数        if (A.size() == i) return B[j+k-1];        //k == 1是递归终止的条件,即分治法最终截止的条件。        if (k == 1) return min(A[i], B[j]);        //pa代表的是数组A的第k/2小数,如果A.size < k/2就取最后一个数,pb同理        int pa = min(i+k/2, int(A.size())), pb = min(j+k/2, int(B.size()));        //按照上述讨论的三种情况,分别递归        if (A[pa-1] < B[pb-1])            return findKth(A, pa, B, j, k-pa+i);//舍弃A[i:pa-1]的数,则从第k小变成了第k-pa+i小        else if (A[pa-1] > B[pb-1])            return findKth(A, i, B, pb, k-pb+j);        else            return A[pa-1];    }

这个代码自己都看着晕乎了,简化一下:

class Solution {public:    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {        int m = nums1.size(), n = nums2.size();        return (findKth(nums1, nums2, (m + n + 1) / 2) + findKth(nums1, nums2, (m + n + 2) / 2)) / 2.0;    }    int findKth(vector<int> nums1, vector<int> nums2, int k) {        int m = nums1.size(), n = nums2.size();        if (m > n) return findKth(nums2, nums1, k);        if (m == 0) return nums2[k - 1];        if (k == 1) return min(nums1[0], nums2[0]);        int i = min(m, k / 2), j = min(n, k / 2);        if (nums1[i - 1] > nums2[j - 1]) {            return findKth(nums1, vector<int>(nums2.begin() + j, nums2.end()), k - j);        } else {            return findKth(vector<int>(nums1.begin() + i, nums1.end()), nums2, k - i);        }        return 0;    }};

参考链接:http://www.cnblogs.com/grandyang/p/4465932.html

原创粉丝点击