力扣刷题记录 4.寻找两个正序数组的中位数

内容:

        1、利用java自带函数破解

        核心思想:两个数组转list合并,由小到大重排序,数组长度奇数直接取中位数的值,为偶数则取中位数和中位数前一位两数合的一半

         时间复杂度O(m+n),空间复杂度O(m+n),m和n分别为两个数组长度

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        double result = 0.0;
        List<Integer> list1 = Arrays.stream(nums1).boxed().collect(Collectors.toList());
        List<Integer> list2 = Arrays.stream(nums2).boxed().collect(Collectors.toList());
        list1.addAll(list2);
        Collections.sort(list1);
        int middle = list1.size()/2;
        if(list1.size()%2==1){
            result = list1.get(middle);
        }else{
            result = (double)(list1.get(middle-1) + list1.get(middle)) / 2;
        }
        return result;
    }
}

        2、不合并数组的解法

        核心思想就是分别控制两个数组的游标取元素比大小,记录每次比较的两个值,left放小值,right放大值,最后两个数组总长度为奇数就直接取right,偶数就是两数的差

        时间复杂度依然是O(m+n),空间复杂度O(1),虽然时间复杂度没变,不过比上面省略了合并数组的空间+重排序的时间

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        double result = 0.0;
        int nums1Index = 0,nums2Index = 0,left = 0,right = 0;
        int sumLength = nums1.length + nums2.length;
        int middle = sumLength / 2;
        for(int i = 0;i <= middle; i++){
            left = right;
            if(nums1Index<nums1.length && 
                (nums2.length<=nums2Index || nums1[nums1Index]<=nums2[nums2Index]) ){
                right = nums1[nums1Index++];
            }else{
                right = nums2[nums2Index++];
            }
        }
        if(sumLength%2==1){
            result = right;
        }else{
            result = (double)(left+right)/2;
        }
        return result;
    }
}

3、二分法

Ps:该解法为力扣题目进阶要求时间复杂度O(log(m+n))的解法,虽然要更复杂一些,不过算法算法,肯定是要精益求精。换句话说,上面两种的确简单,但大部分人都可以写出来,是否实用暂且不论,泯然众人矣。

时间复杂度O(log(m+n)),空间复杂度O(1) 

public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int sumLength = nums1.length + nums2.length;
        int k = sumLength / 2 + 1;
        if(sumLength % 2 == 1){
            return queryK(nums1,nums2,k);
        }else{
            return (double)(queryK(nums1,nums2,k - 1) + queryK(nums1,nums2,k)) / 2;
        }
    }

    public static double queryK(int[] nums1, int nums2[], int k){
        int index1 = 0,index2 = 0;
        while(true){
            if(index1 > nums1.length - 1){
                return (double)nums2[index2 + k - 1];
            }
            if(index2 > nums2.length - 1){
                return (double)nums1[index1 + k - 1];
            }
            if(k==1){
                return Math.min(nums1[index1],nums2[index2]);
            }
            int half = k / 2;
            int newIndex1 = Math.min(nums1.length - 1,index1 + half - 1);
            int newIndex2 = Math.min(nums2.length - 1,index2 + half - 1);
            if(nums1[newIndex1] <= nums2[newIndex2]){
                k -= (newIndex1 - index1 + 1);
                index1 = newIndex1 + 1;
            }
            else{
                k -= (newIndex2 - index2 + 1);
                index2 = newIndex2 + 1;
            }
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值