复习:找出两个正序数组的中位数


思路
  题目要求对数时间复杂度,所以立马反应出用二分法;从宏观的角度,本题二分法的思路就是,通过每一次,丢弃k/2个数,直到最后让你比较两个正序数组里的最小数,也就是k==1的情况;
  <mark>然后就是细节细节再细节的边界问题;如果,在丢弃数据的过程中,有一个数组遍历完了,那么问题变成在一个数组里面寻找某一个数;</mark>

代码分析

class Solution {
   
public:
    double getKthNumInTwoSortedArrays(vector<int>& nums1, vector<int>& nums2,int k){
   
        //假设两个数组各贡献k/2,然后每一次可以k/2,直到最终让你找出两个数中的最小数
        //可能存在的边界条件,k还没有等于1,其中一个数组已经到达了末尾,那么就相当于在一个数组里面取一个数
        int ai=0,bi=0;
        int len1=nums1.size();
        int len2=nums2.size();

        while(true){
   
            if(ai==nums1.size())
                return nums2[bi+k-1];
            if(bi==nums2.size())
                return nums1[ai+k-1]; 
            if(k==1)    
                return std::min(nums1[ai],nums2[bi]);
            int new_ai=std::min(ai+k/2-1,len1-1);
            int new_bi=std::min(bi+k/2-1,len2-1);

            int pivot_a=nums1[new_ai];
            int pivot_b=nums2[new_bi];
            if(pivot_a<=pivot_b){
   //可以丢弃nums1中的前k/2个元素
                k-=new_ai-ai+1;
                ai=new_ai+1;
            }else {
   
                k-=new_bi-bi+1;
                bi=new_bi+1;
            }
        }
    }
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
   
        //时间复杂度O(log(m+n))立马想到二分法
        //可以把题目升华为找到两个升序数组里的第k个数
        int len=nums1.size()+nums2.size();
        if(len%2!=0)
            return getKthNumInTwoSortedArrays(nums1,nums2,len/2+1);
        else 
            return (getKthNumInTwoSortedArrays(nums1,nums2,len/2)+getKthNumInTwoSortedArrays(nums1,nums2,len/2+1))/2;
    }
};

细节之处见真章

 if(k==1)    
                return std::min(nums1[ai],nums2[bi]);
                //return std::min(nums1[0],nums2[0]);

此处 ,最开始写成了下面一行,竟也没有察觉到;由于在不断的丢弃数据的过程中,最终可能就变成了在两个数组中,找出最小值;由于我们“丢弃”不是真的把数据丢掉了,只是首下标的偏移而已!!!

刷题总结类 文章被收录于专栏

这里记录一些刷题时候的总结思考

全部评论

相关推荐

拉丁是我干掉的:把上海理工大学改成北京理工大学。成功率增加200%
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务