LeetCode04-寻找两个正序数组的中位数

LeetCode04-寻找两个正序数组的中位数

Leetcode / 力扣

4.寻找两个正序数组的中位数:

给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的中位数 。

示例 1:

输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2

示例 2:

输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5

示例 3:

输入:nums1 = [0,0], nums2 = [0,0]
输出:0.00000

示例 4:

输入:nums1 = [], nums2 = [1]
输出:1.00000

示例 5:

输入:nums1 = [2], nums2 = []
输出:2.00000

提示:

  • nums1.length == m
  • nums2.length == n
  • 0 <= m <= 1000
  • 0 <= n <= 1000
  • 1 <= m + n <= 2000
  • -106 <= nums1[i], nums2[i] <= 106

解题思路1:

暴力归并,时间复杂度:O(n+m)

class Solution {
public:
    double findMedianSortedArrays(vector& nums1, vector& nums2) {
        vectortmp;
        int len1=nums1.size();
        int len2=nums2.size();
        int i=0,j=0,k=0;
        while(i>1;
        if((len1+len2)%2)
            ans=tmp[mid]*1.0;
        else
            ans=(tmp[mid]+tmp[mid-1])*0.5;
        return ans;
    }

};

解题思路2:

二分,寻找两个数组的第K大,时间复杂度:O(log(n+m))

class Solution {
    int find_Kth(vector& nums1, vector& nums2,int k){
        int n=nums1.size();
        int m=nums2.size();
        int index1=0;
        int index2=0;
        while(true)
        {
            if(index1==n)
                return nums2[index2+k-1];
            if(index2==m)
                return nums1[index1+k-1];
            if(k==1)
                return nums1[index1]<=nums2[index2]?nums1[index1]:nums2[index2];
            
            int newindex1=index1+k/2-1;
            int newindex2=index2+k/2-1;
            if(newindex1>=n)
                newindex1=n-1;
            if(newindex2>=m)
                newindex2=m-1;
            
            if(nums1[newindex1]<=nums2[newindex2])
            {
                k-=newindex1-index1+1;
                index1=newindex1+1;
            }
            else
            {
                k-=newindex2-index2+1;
                index2=newindex2+1;
            }
            
        }
        
    }
public:
    double findMedianSortedArrays(vector& nums1, vector& nums2) {
        int n=nums1.size();
        int m=nums2.size();

        if((n+m)%2==0)
            return (find_Kth(nums1,nums2,(n+m)/2)+find_Kth(nums1,nums2,(n+m)/2+1))*0.5;
        else
            return find_Kth(nums1,nums2,(n+m+1)/2);
    }
};

解题思路3:

困难题,官方题解写得挺好的,传送门
数组划分,二分 (二分太难了,细节过于难扣,一定要注意边界判断条件!!!包括但不限于l和r的初始值,if、else里面的判断条件,何时更新答案)

class Solution {
public:
    double findMedianSortedArrays(vector& nums1, vector& nums2) {
        int n = nums1.size(),m=nums2.size();

        //如果第一个数组长度要小,则需要交换
        if(n>m){
            return findMedianSortedArrays(nums2,nums1);
        }

        int i,pre_i,j,pre_j,l=0,r=n;    //这里必须从n开始,因为数组划分的原因,要把第一个数组的所有数都分进去,i就必须取到n(下标从0开始)
        int Median1,Median2;

        while(l<=r){
            int nums_i,nums_j,nums_prei,nums_prej;
            int mid = (l+r)>>1;
            i=mid;
            j=(n+m+1)/2-i;

            nums_i = (i==n) ? INT_MAX : nums1[i];
            nums_j = (j==m) ? INT_MAX : nums2[j];
            nums_prei = (i==0) ? INT_MIN : nums1[i-1];
            nums_prej = (j==0) ? INT_MIN : nums2[j-1];

            printf("%d %d %d %d %d %d\n",i,j,nums_i,nums_j,nums_prei,nums_prej);

            if(nums_prei<=nums_j){
                l=mid+1;
                Median1 = max(nums_prei,nums_prej);
                Median2 = min(nums_i,nums_j);
                printf("1: %d\n",Median1);
                printf("2: %d\n",Median2);
            }else{
                //缩小区间不能更新值答案Median,因为不符合条件
                r=mid-1;
            }

        }
        printf("%d %d\n",Median1,Median2);
        return ((m+n)%2==1) ? Median1 : (Median1+Median2)/2.0;
    }
};

你可能感兴趣的:(LeetCode题解,leetcode,算法,c语言,二分法)