zoukankan      html  css  js  c++  java
  • LeetCode4. Median of Two Sorted Arrays(二分法)

    题解

    划分元素组

    长数组a,短数组b

    数组 元素组1 元素组2
    a(长度为m) a1,a2,a3...ai ai+1,ai+2...am-1,am
    b(长度为n) b1,b2,b3...bj bj+1,bj+2...bn-1,bn

    划分保证元素组1中元素一定小于等于元素组2中的元素,且size(元素组1)-size(元素组2)的绝对值最小。

    1. 若m+n为偶数,划分之后size(元素组1)==size(元素组2)。则中位数一定是ai,ai+1,bj,bj+1这四个数中两个数的平均数。
    2. 若m+n为奇数,划分之后size(元素组1)+1==size(元素组2)。则中位数一定是ai,ai+1,bj,bj+1这四个数中的一个。

    如何划分数组

    1. 划分长数组,因为长数组中的元素能定位短数组中的不同元素(也可能定位不到),而短数组定位长数组中的元素是受限的。
    2. 根据长数组元素定位短数组元素。
      考虑如下情况。
      短数组a = {3};
      长数组b = {1,2,4,5,6};
      若用短数组去定位长数组,则a0总是定位到b3(下标=(m+n)/2-0=3,采用不同的计算方法可以得到不同的下标),而b3=5,显然不是中位数。

    确定中位数的值

    1. 若m+n为偶数,则ans = (max(ai,bj)+min(ai+1,bj+1))/2;
    2. 若m+n为奇数,由于元素组2比元素组1个数多一个,中位数一定存在于ai+1,bj+1,则ans = min(ai+1,bj+1);

    Code

    class Solution {
    public:
        double findMedianSortedArrays(vector<int>& a, vector<int>& b) {
            // m,n表示两vector数组的大小。
            int m = a.size();
            int n = b.size();
            // 若a数组长度小于b数组,则交换两数组。因为我们要根据长数组元素定位短数组中的对应元素
            if(m < n) return findMedianSortedArrays(b,a);
            int l = 0, r = m;
            double ans;
            int mid1, mid2,left1,left2,right1,right2;
    	    while (l < r) {
    	        // mid1为二分数组a,mid2对应mid1取值
    		    mid1 = (l + r) / 2;
    		    mid2 = (m + n) / 2 - mid1;
                
                // 如果mid2越界,调整l和r,重新确定mid1。
                if(mid2 < 0){
                    r = mid1;
                    continue;
                }
                if(mid2 > n){
                    l = mid1+1;
                    continue;
                }
                // 取出a[i]、a[i+1]、b[j]、b[j+1]。左边越界,设为最小值;右边越界,设为最大值。
    		    left1 = mid1 - 1 <= -1 ? INT_MIN : a[mid1 - 1];
    		    right1 = mid1 >= m ? INT_MAX : a[mid1];
    		    left2 = mid2 - 1 <= -1 ? INT_MIN : b[mid2 - 1];
    		    right2 = mid2 >= n ? INT_MAX : b[mid2];
    
                // 如果满足左边元素组小于等于右边元素组,跳出循环
    		    if (right1 >= left2 && left1 <= right2) {
    			    break;
    		    }
    		    // 如果不满足,则调整l,r重新取mid1。
    		    if (right1 < left2) {
    			    l = mid1+1;
    		    }
    		    if (left1 > right2) {
    			    r = mid1;
    		    }
    	    }
    	    //如果为奇数
            if (1 & (m + n)) {
                ans = 1.0*min(right1, right2);
    	    }
    	    else {
    	        ans = 1.0*(max(left1, left2) + min(right1, right2)) / 2;
            }
            return ans;
        }
    };
    
  • 相关阅读:
    赫尔维茨公式
    从解析几何的角度分析二次型
    Struts 1 Struts 2
    记一次服务器被入侵的调查取证
    契约式设计 契约式编程 Design by contract
    lsblk df
    Linux Find Out Last System Reboot Time and Date Command 登录安全 开关机 记录 帐号审计 历史记录命令条数
    Infrastructure for container projects.
    更新文档 版本控制 多版本并发控制
    Building Microservices: Using an API Gateway
  • 原文地址:https://www.cnblogs.com/zhangjiuding/p/13271640.html
Copyright © 2011-2022 走看看