• Leetcode: 4. Median of Two Sorted Arrays


    Description

    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

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

    思路

    • 每次做这个题都要纠结半天。好好理理吧。
    • 此题的另一种通用形式为:给定两个已经排好序的数组,找到两者所有元素中第K大的元素
      • 分析1:O(m+n), 直接merge, 然后找出第k大的数。 可以部分优化,即i = 0, pa = 0, pb = 0, 然后比较,若 A[pa] < B[pb],则i++, pa++。同理。。然后直接到第K大元素即可。当K接近(m+n)时,优化不大
      • 分析2:O(log(m + n)), 二分
        • 假设A和B中的元素个数都大于k/2,我们将A的第k/2个元素(即A[k/2 - 1])和B的第k/2个元素相比较,可以得到:
          • A[k/2 - 1] == B[k/2 - 1]
          • A[k/2 - 1] < B[k/2 - 1]
          • A[k/2 - 1] > B[k/2 - 1]
        • 如果A[k/2 - 1] 小于B[k/2 - 1],这说明A[0]到A[k/2 - 1]这部分元素肯定在top k范围内,所以可以删除A的这k/2个元素。同理A[k/2 - 1] > B[k/2 - 1]时,可以删除B的这k/2个元素
        • 当A[k/2 - 1] == B[k/2 - 1]时,说明找到第K大的元素,直接返回A[k/2-1]或B[k/2-1]
        • 因此,我们可以写一个递归函数。那么函数什么时候应该终止呢?
          • 当 A 或 B 是空时,直接返回 B[k-1] 或 A[k-1];
          • 当 k=1 是,返回 min(A[0], B[0]);
          • 当 A[k/2-1] == B[k/2-1] 时,返回 A[k/2-1] 或 B[k/2-1]

    代码

    • 时间复杂度 O(log(m+n))
    class Solution {
    public:
        double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
            int len1 = nums1.size();
            int len2 = nums2.size();
            
            if(len1 == 0 && len2 == 0)
                return 0;
            else if(len1 == 0){
                return len2 % 2 == 0 ? ((nums2[len2/2 - 1] + nums2[len2/2])/2.0 ): nums2[len2 / 2]; 
            }else if(len2 == 0){
                 return len1 % 2 == 0  ? ((nums1[len1/2 - 1] + nums1[len1/2]) / 2.0) : nums1[len1 / 2]; 
            } 
            
            int total = len1 + len2;
            
            if(total & 0x1)
                return find_kth(&(*nums1.begin()), len1, &(*nums2.begin()), len2, total / 2 + 1);
            else{
                return  (find_kth(&(*nums1.begin()), len1, &(*nums2.begin()), len2, total / 2)
                   + find_kth(&(*nums1.begin()), len1, &(*nums2.begin()), len2, total / 2 + 1)) / 2.0;
            }
        }
        
    private:
        int find_kth(int *A, int m, int *B, int n, int k){
            if(m > n) return find_kth(B, n, A, m, k);
            if(m == 0) return B[k - 1];
            if(k == 1) return min(A[0], B[0]);
            
            int ia = min(k / 2, m), ib = k - ia;
            if(A[ia - 1] < B[ib - 1])
                return find_kth(A + ia, m - ia, B, n, k - ia);
            else if(A[ia - 1] > B[ib - 1])
                return find_kth(A, m, B + ib, n - ib, k - ib);
            return A[ia - 1];
        }
    };
    
  • 相关阅读:
    Java后台实现方法
    解决横屏下锁屏,再次解锁界面显示异常-一屏下显示反复两个界面
    java平台利用jsoup开发包,抓取优酷视频播放地址与图片地址等信息。
    用C++实现一个Log系统
    LeetCode 3_Longest Substring Without Repeating Characters
    跟着实例学习设计模式(7)-原型模式prototype(创建型)
    XStream 数组(List)输出结构
    【Cocos2d-x 3.0 基础系列一】 各类回调函数写法汇总
    机房收费系统验收小结(一)
    动态隐藏/显示系统状态栏
  • 原文地址:https://www.cnblogs.com/lengender-12/p/6757843.html
Copyright © 2020-2023  润新知