【LeetCode刷题】4.寻找两个正序数组的中位数

题目描述

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

算法的时间复杂度应该为 O(log (m+n)) 。

示例 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

提示:

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

题解思路

基本情况

设置一个n变量用于记录已经遍历的元素个数,设置i,j变量用于记录两个数组下一次需要遍历的元素。
判断nums1[i]与nums2[j]的大小关系,小的那个数组下标进一,并将n自增。
重复上述操作直到n自增到中位数所在的位置,最后输出中位数的值。

特殊情况

某一个数组已经遍历完了,但n还没有到达中位数所在的位置,就不需要判断nums1[i]与nums2[j]的大小关系了,只需要将未遍历完的数组继续遍历即可。

题解代码

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int lengthSum = nums1.length + nums2.length;
        if(lengthSum%2 == 0){
            int stop = lengthSum/2;
            int i = 0,j = 0;//i用于记录第一个数组下一次该遍历哪一个,j用于记录第二个数组下一次遍历哪一个
            int n = 0;//n用于记录已经遍历的元素个数
            double mid = 0;
            while(n<stop-1){
                if(i==nums1.length){
                    n++;
                    j++;
                }
                else if(j==nums2.length){
                    n++;
                    i++;
                }
                else if(nums1[i]<nums2[j]){
                    n++;
                    i++;
                }
                else{
                    n++;
                    j++;
                }
            }
            if(i==nums1.length){
                mid += nums2[j];
                j++;
            }
            else if(j==nums2.length){
                mid += nums1[i];
                i++;
            }
            else if(nums1[i]<nums2[j]){
                mid += nums1[i];
                i++;
            }
            else{
                mid += nums2[j];
                j++;
            }
            if(i==nums1.length){
                mid += nums2[j];
            }
            else if(j==nums2.length){
                mid += nums1[i];
            }
            else if(nums1[i]<nums2[j]){
                mid += nums1[i];
            }
            else{
                mid += nums2[j];
            }
            return mid/2;
        }
        else{
            int stop = (lengthSum+1)/2;
            int i = 0,j = 0;//i用于记录第一个数组下一次该遍历哪一个,j用于记录第二个数组下一次遍历哪一个
            int n = 0;//n用于记录已经遍历的元素个数
            double mid = 0;
            while(n<stop-1){
                if(i==nums1.length){
                    n++;
                    j++;
                }
                else if(j==nums2.length){
                    n++;
                    i++;
                }
                else if(nums1[i]<nums2[j]){
                    n++;
                    i++;
                }
                else{
                    n++;
                    j++;
                }
            }
            if(i==nums1.length){
                mid = nums2[j];
            }
            else if(j==nums2.length){
                mid = nums1[i];
            }
            else if(nums1[i]<nums2[j]){
                mid = nums1[i];
            }
            else{
                mid = nums2[j];
            }
            return mid;

        }
    }
}

优化思路

直接开辟一个新的数组,将两个数组合并成一个新的有序数组之后再计算中位数,思路更清晰,实现更简便。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值