【力扣hot100题】(067)寻找两个有序数组的中位数

我觉得这是目前hot里最难的题了,不敢想象面试碰到这等恐怖的题会是怎样一番腥风血雨。

大体思路其实不难(找到正确方法途径实现还是有难度的),难点主要集中在情况巨多,但凡这题给定两数组长度之和一定为奇数都不会这么难。

思路想了好一会,我先是想到每次取两数组的中间值比较,将大的那个后面的元素全部剔除,但这种方法需要记录原始数组长度、剔除的长度,每次都要比较是否剔除了一半的原长度……

看来答案才发现可以从前往后剔除,思路其实差不多但是实现起来答案确实更简单。

我最终的方法结合了答案和自己的想法:先记录需要找的位置k=(nums1.size()+nums2.size()-1)/2,同样是每次找寻中间节点k/2比较,剔除中间值小的那个数组的右边部分,k减去剔除的值,每个循环检查k,若k为0则取两数组首位更小的那个值。

这还只是大体思路,还有很多其余情况,比如一个数组的长度达不到k/2,这时候就取这个数组的最后一个元素和另一个数组中间点比较;还有一个数组已经为空,这时候取另一个数组的第k个位置即可;还有需要加入bool判断有几个中位数,如果有两个就还要取下一个最小值与当前最小值相加除以二……

总之最终还是“顺利”的过了。

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        bool b=(nums1.size()+nums2.size())%2;
        int k=(nums1.size()+nums2.size()-1)/2;
        while(1){
            if(nums1.size()==0){
                if(b==1) return nums2[k];
                else return static_cast<double>(nums2[k]+nums2[k+1])/2;
            }
            if(nums2.size()==0){
                if(b==1) return nums1[k];
                else return static_cast<double>(nums1[k]+nums1[k+1])/2;
            }
            if(k==0){
                if(b==1) return min(nums1[0],nums2[0]);
                else if(nums2.size()>1&&nums1[0]>nums2[0]) return static_cast<double>(nums2[0]+min(nums1[0],nums2[1]))/2;
                else if(nums1.size()>1&&nums1[0]<nums2[0]) return static_cast<double>(nums1[0]+min(nums1[1],nums2[0]))/2;
                else return static_cast<double>(nums1[0]+nums2[0])/2;
            }
            if(nums1.size()<=k/2){
                if(nums1[nums1.size()-1]>nums2[k/2]){
                    nums2.erase(nums2.begin(),nums2.begin()+(k+1)/2);
                    k-=(k+1)/2;
                }
                else{
                    k-=nums1.size();
                    nums1.clear();
                }
            }
            else if(nums2.size()<=k/2){
                if(nums2[nums2.size()-1]>nums1[k/2]){
                    nums1.erase(nums1.begin(),nums1.begin()+(k+1)/2);
                    k-=(k+1)/2;
                }
                else{
                    k-=nums2.size();
                    nums2.clear();
                }
            }
            else if(nums1[k/2]>nums2[k/2]){
                nums2.erase(nums2.begin(),nums2.begin()+(k+1)/2);
                k-=(k+1)/2;
            }
            else{
                nums1.erase(nums1.begin(),nums1.begin()+(k+1)/2);
                k-=(k+1)/2;
            }
        }
        return 0;
    }
};

前三个if都是判断是否可以return了,后面的一系列if else都是移动k和删除元素。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值