leetcode每日刷题计划--day58

Num 4 寻找两个有序数组的中位数

啊啊啊啊啊啊啊wa了无数次卡了两天我终于给这个整出来了!!!

方法很简单,各种边界条件超级无敌坑爹。

看到log就想二分。target就是中位数,或者用来取平均的两个数

target中两个数组分别占有多少部分。然后如果正常情况下,用两个里面最大的比较就行。

判断合法的是,每个数组target范围内的最后一个数比另外一个target外面的第一个数大。

需要注意的是:如果已经到了边界点,说明现有的这些都是合理的。那么这个不用比较了(因为你在上面一轮已经比较过了,确实是需要调整,才会变成现有的,所以当前是合法的)(但是两个比较条件另外一个是需要比较的)

几个要点:

  1、因为需要合法/跳出特殊写的情况非常多,这里面选择先写非边界继续运行然后继续二分的状态

  2、在跳出来的情况里面,存在一定可能:虽然一条不用比较,但是需要比较的另一条不符合的

  3、这种情况的修改中,要考虑到往前移动可能触碰另一边边界

  4、并不能直接确定是在a中还是在b中,这时候用target内最后两个比较

  5、如果有范围内没有的,给个标记,让他们直接从另一个组取

  6、最开始加个判定,如果整体一个数组小于另外一个数组,这时候省掉二分时间。

class Solution {
public:
    double getNum(vector<int>&nums1,vector<int>&nums2,int target)
    {
        if(nums1.size()==0)
            return nums2[target-1];
        if(nums1[nums1.size()-1]<=nums2[0])
        {
            if(target<=nums1.size())
                return nums1[target-1];
            return nums2[target-nums1.size()-1];
        }
        if(nums2[nums2.size()-1]<=nums1[0])
        {
            if(target<=nums2.size())
                return nums2[target-1];
            return nums1[target-nums2.size()-1];
        }
        int l=1,r=nums1.size();
        int m=(l+r)/2;//mb=target-m+1;都是第几个a[m-1] b[target-m]
        while(l<=r)
        {
            if(m<nums1.size() && target-m<nums2.size() && nums1[m-1]>nums2[target-m])
                {r=m-1;m=(l+r)/2;continue;}
            if(m<nums1.size() && target-m<nums2.size() && nums2[target-m-1]>nums1[m])
                {l=m+1;m=(l+r)/2;continue;}
            break;
        }
            int leftans=m-1,rightans=target-m-1;
            if(target-m==nums2.size() && nums2[target-m-1]>nums1[m])
            {
                do
                {
                    leftans++;
                    rightans--;
                }while(rightans>=0 && leftans<=nums1.size()-2 && nums2[rightans]>nums1[leftans+1]);
            }
            //cout<<"hh";
            if(m==nums1.size() && nums1[m-1]>nums2[target-m])
            {
                do
                {
                    leftans--;
                    rightans++;
                }while(leftans>=0 && rightans<=nums2.size()-2 && nums1[leftans]>nums2[rightans+1]);
            }
            //cout<<leftans<<rightans<<endl;
            if(leftans<0) return nums2[target-1];
            if(rightans<0) return nums1[target-1];
            return max(nums1[leftans],nums2[rightans]);
        return 1;
    }
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int len1=nums1.size();
        int len2=nums2.size();
        if(len1>len2)
            swap(nums1,nums2);
        int len=len1+len2;
        //getNum后面的数是排序,不是下标。
        if(len%2)
            return getNum(nums1,nums2,len/2+1);
        else
            return (getNum(nums1,nums2,len/2)+getNum(nums1,nums2,len/2+1))*1.0/2;
    }
};
View Code

猜你喜欢

转载自www.cnblogs.com/tingxilin/p/11921159.html