Median of Two Sorted Arrays

Median of Two Sorted Arrays

There are two sorted arrays nums1 and nums2 of size m and n respectively.

Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

Example 1:

nums1 = [1, 3]
nums2 = [2]
The median is 2.0

Example 2:

nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5

Solution:

起初沒有看到要求的時間複雜度,最原始的想法就是把它們兩個合在一起然後排序取中值就好。由於sort函數時間複雜度爲O(NlogN),所以下面算法時間複雜度爲O((m+n)log(m+n))
class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        vector<int> total;
        for(int i = 0; i < nums1.size(); i++)
        {
            total.push_back(nums1[i]);
        }
        for(int i = 0; i < nums2.size(); i++)
        {
            total.push_back(nums2[i]);
        }
        std::sort(total.begin(), total.end());
        if(total.size() % 2 == 0) return (double)(total[total.size() / 2 - 1] + total[total.size() / 2]) * 0.5;
        else return (double)total[total.size() / 2];
    }
};

對算法進行改進以滿足時間複雜度要求。

嘗試在同一函數內尋找第K個值,可是失敗了,下面函數有很多的bug,也有很多的重複之類的。放假玩崩了算了我放棄改了。

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int n = nums1.size();
        int m = nums2.size();
        
        if (n > m) return findMedianSortedArrays(nums2, nums1);
        
        if (n == 0)
        {
            if (m % 2 == 0) return (double)(nums2[(m - 1) / 2] + nums2[m / 2]) * 0.5;
            else return (double)(nums2[(m - 1) / 2]);
        }
        if (m == 0)
        {
            if (n % 2 == 0) return (double)(nums1[(n - 1) / 2] + nums1[n / 2]) * 0.5;
            else return (double)(nums1[(n - 1) / 2]);
        }
        
        int k = (n + m - 1) / 2; //k 爲中位數所在個數      
        int r = k, l = 0, j = k - n + 1;
        while(nums2[r] > nums1[l])
        {
            if(r == 0) break;
            int midB = (j + r) / 2;
            int midA = k - midB;
            if(midB == r) break;
            if (nums1[midA] < nums2[midB])
            {
                r = midB;
                l = midA;
            }
            else
            {
                j = midB;
            }
            if (midA != n-1 && nums1[midA + 1] >= nums2[midB])
            {
                r = midB;
                l = midA;
                break;
            }
            if (midA == n - 1)
            {
                r = midB;
                l = midA;
                break;
            }
        }
        int A, B;
        if(l == n - 1 && l != 0 && nums1[l - 1] > nums2[r] && r != m - 1 && nums1[l] > nums2[r + 1])
        {
            A = nums1[l - 1] < nums2[r + 1] ? nums1[l - 1] : nums2[r+1];
            B = nums1[l - 1] > nums2[r + 1] ? nums1[l - 1] : nums2[r+1];
        }
        else if(l == n - 1 && r != m - 1 && nums1[l] > nums2[r + 1])
        {
            A = nums2[r];
            B = nums2[r + 1];
        }
        else if(l == n - 1 && l != 0 && nums1[l - 1] > nums2[r])
        {
            A = nums1[l - 1];
            B = nums1[l];
        }
        else if(r > 0 && nums2[r - 1] > nums1[n - 1])
        {
            A = nums2[r - n];
            B = nums2[r - n + 1];
        }
        else if (r > 0 && nums2[r] < nums1[0])
        {
            if (r < m - 1 && nums2[r + 1] < nums1[0])
            {
                A = nums2[r];
                B = nums2[r + 1];   
            }
            else if(r == m - 1)
            {
                A = nums2[r];
                B = nums2[r + 1];
            }
        }
        else
        {
            A = nums1[l] < nums2[r] ? nums1[l] : nums2[r];
            B = nums1[l] >= nums2[r] ? nums1[l] : nums2[r];   
        }

        if ((n + m) % 2 == 1) return A;
        return (A+B) / 2.0;
    }
};

用遞歸算法成功得完成了該題目,時間複雜度爲O(log(M + N))
class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int a = nums1.size();
        int b = nums2.size();
        int k = (a + b ) / 2;
        int result1 = Kth(nums1.begin(), a, nums2.begin(), b, k + 1);
        if ((a + b) % 2 == 0) {
            int result2 = Kth(nums1.begin(), a, nums2.begin(), b, k);
            return ( (double) result1 + result2) / 2.0;
        }
        return result1;
    }
    int  Kth(vector<int>::iterator start1, int a, vector<int>::iterator start2, int b, int k) {
        if (a > b) return Kth(start2 , b, start1, a, k);
        if (a == 0) return *(start2 + k - 1);
        if (k == 1) return *start1 < *start2 ? *start1 : *start2;
        int i = a < (k / 2) ? a : (k / 2);
        int j = k - i;
        if (*(start1 + i - 1) > *(start2 + j - 1)) 
            return Kth(start1, a , start2 + j, b - j, k - j);
        return Kth(start1 + i, a - i, start2, j, k - i);
    }
};



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章