zoukankan      html  css  js  c++  java
  • 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
    时间才能证明一切,选好了就尽力去做吧!
  • 相关阅读:
    [转]Java中实现自定义的注解处理器
    [转]IntelliJ IDEA 自定义方法注解模板
    [转]Intellij Idea自动添加注释的方法
    C++中substr的用法
    C++中find()函数和rfind()函数的用法
    无符号类型
    标准库string与C风格字符串
    vector对象
    string 类(二)
    string类
  • 原文地址:https://www.cnblogs.com/tingxilin/p/11921159.html
Copyright © 2011-2022 走看看