LeetCode #4 简单题

题目: 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。你可以假设 nums1 和 nums2 不会同时为空。

题解: 一开始没看到要求时间是log(m + n),直接俩下标标记过去了,时间复杂度是 (m + n) / 2。先贴一下这个版本的代码,不过就算这样LeetCode也给过了= =。

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int n = (int)nums1.size(), m = (int)nums2.size();
        int left1 = 0, left2 = 0;
        int numleft1 = 0, numleft2 = 0;
        while (left1 + left2 < (n + m) / 2 + 1){
            numleft1 = numleft2;
            if (left1 == n) numleft2 = nums2[left2++];
            else if (left2 == m) numleft2 = nums1[left1++];
            else {
                if (nums1[left1] < nums2[left2]) numleft2 = nums1[left1++];
                else numleft2 = nums2[left2++];
            }
        }
        
        if ((n + m) & 1) return numleft2;
        else return (double)(numleft1 + numleft2) / 2.0;
    }
};

接下来是log(n + m) 的代码,思路就是二分,从第一个数组找一个位置 x,第二个数组中找一个位置 y,其中 y = (m + n + 2x) / 2,使得找到的x,y左边的数都大于右边的数即可。

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int m = nums1.size();
        int n = nums2.size();
        if (m == 0) {
            if (n % 2 != 0)
                return 1.0 * nums2[n / 2];
            return (nums2[n / 2] + nums2[n / 2 - 1]) / 2.0;
        }
        if (n == 0) {
            if (m % 2 != 0)
                return 1.0 * nums1[m / 2];
            return (nums1[m / 2] + nums1[m / 2 - 1]) / 2.0;
        }
        int total = m + n;
        if ((total & 1) == 1) {
            return find_kth(nums1, 0, nums2, 0, total / 2 + 1);
        }
        return (find_kth(nums1, 0, nums2, 0, total / 2) + find_kth(nums1, 0, nums2, 0, total / 2 + 1)) / 2.0;

    }

    double find_kth(vector<int>& a, int a_begin, vector<int>& b, int b_begin, int k) {
        if (a_begin >= a.size())
            return b[b_begin + k - 1];
        if (b_begin >= b.size())
            return a[a_begin + k - 1];
        if (k == 1)
            return min(a[a_begin], b[b_begin]);

        int mid_a = 0x7fffffff;
        int mid_b = 0x7fffffff;
        if (a_begin + k / 2 - 1 < a.size())
            mid_a = a[a_begin + k / 2 - 1];
        if (b_begin + k / 2 - 1 < b.size())
            mid_b = b[b_begin + k / 2 - 1];
        if (mid_a < mid_b)
            return find_kth(a, a_begin + k / 2, b, b_begin, k - k / 2);
        return find_kth(a, a_begin, b, b_begin + k / 2, k - k / 2);
    }
};

猜你喜欢

转载自www.cnblogs.com/error408/p/11582116.html