• 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;
        }
    };
    
  • 相关阅读:
    Git 简单使用
    java web 简单的分页显示
    java web 实现验证码
    第一个MapReduce程序
    xgboost安装指南(win10,win7 64位)
    受限玻尔兹曼机(Restricted Boltzmann Machine)分析
    卷积神经网络概述及python实现
    集体智慧编程_第二章(提供推荐)_1
    EditText的inputType常用取值
    关于泛型的一些细节
  • 原文地址:https://www.cnblogs.com/zhangjiuding/p/13271640.html
Copyright © 2020-2023  润新知