zoukankan      html  css  js  c++  java
  • leetcode: Median of Two Sorted Arrays

    本文通过MetaWeblog自动发布,原文及更新链接:https://extendswind.top/posts/technical/leetcode4

    题目

    Median of Two Sorted Arrays There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). You may assume nums1 and nums2 cannot be both empty. Example 1: nums1 = [1, 3] nums2 = [2] The median is 2.0 Example 2: nums1 = [1, 2] nums2 = [3, 4] The median is (2 + 3)/2 = 2.5

    主要思想

    为找到合适的位置划分两个数组:

    在nums1和nums2两个数组中分别截取i,j两个长度,将两个数组划分成4部分,使

    • 划分后两个数组的左部分的数量和与右部分数量和相等 i+j == (m+n)/2 (奇数偶数情况都满足此式) &&
    • 左部分的最大值小于右部分的最小值 max(nums1[i-1], nums2[j-1]) < min(nums1[i], nums2[j]) (由于数组有序)

    注: i==0时,nums所有元素被分配到右方; i==nums1.length时,nums所有元素被分到左方

    则:

    • 当m+n为偶数时,(max(nums1[i-1], nums1[j-1]) + min(nums1[i], nums2[j]))/2对应的位置为中位数的位置
    • 当m+n为奇数时,max(nums1[i-1], nums1[j-1])对应的位置为中位数的位置

    具体实现

    在nums1中二分查找i,对于每个i可以直接计算 j=(m+n)/2-i,然后判断是否满足条件,不满足条件则继续搜索。

    主要的麻烦在于处理几个极端情况,i、j为0和长度为最大时。

    leetcode题目的解决方案提到需要让i成为较长的数组,上面的处理没用到。

    此时算法复杂度为O(log(m)),将数组调换位置,每次搜索较短的数组,能够将算法复杂度降低到O**(log(min(m,n)))。

    class Solution {
        public double findMedianSortedArrays(int[] nums1, int[] nums2) {
            if (nums1.length == 0)
                return (nums2[(nums2.length - 1) / 2] + nums2[nums2.length / 2]) / 2.0;
            if (nums2.length == 0) // return median of nums1
                return (nums1[(nums1.length - 1) / 2] + nums1[nums1.length / 2]) / 2.0;
    
            int iMin = 0;
            int iMax = nums1.length;
            int i;  // represent begin of right array of divided position, range in [0, nums1.length]
            // i = 0 means all nums1 will be put in right
            // i = nums1.length means all nums1 will be put in left
    
            while (iMin <= iMax) {
                i = (iMin + iMax) / 2;
    
                int j = (nums1.length + nums2.length) / 2 - i;  // range in [0, jNum.length]
                if (j < 0) {
                    iMax = i - 1;
                    continue;
                } else if (j > nums2.length) {
                    iMin = i + 1;
                    continue;
                }
    
                int leftEnd1; // end element of left part in nums1
                int leftEnd2;
                int rightBegin1;
                int rightBegin2;
    
                //  nums1 may be all put to right(==0) or left(==nums1.length)
                if (i == 0) {
                    leftEnd1 = Integer.MIN_VALUE; // leftEnd1 is not existed
                    rightBegin1 = nums1[i];
                } else if (i == nums1.length) {
                    leftEnd1 = nums1[i - 1];
                    rightBegin1 = Integer.MAX_VALUE;
                } else {
                    leftEnd1 = nums1[i - 1];
                    rightBegin1 = nums1[i];
                }
    
                //  nums2 may be all put to right(==0) or left(==nums2.length)
                if (j == 0) {
                    leftEnd2 = Integer.MIN_VALUE;
                    rightBegin2 = nums2[j];
                } else if (j == nums2.length) {
                    leftEnd2 = nums2[j - 1];
                    rightBegin2 = Integer.MAX_VALUE;
                } else {
                    leftEnd2 = nums2[j - 1];
                    rightBegin2 = nums2[j];
                }
    
                int maxLeftEnd = Math.max(leftEnd1, leftEnd2);
                int minRightBegin = Math.min(rightBegin1, rightBegin2);
    
                if (maxLeftEnd <= minRightBegin) {
                    if ((nums1.length + nums2.length) % 2 == 0)
                        return (minRightBegin + maxLeftEnd) / 2.0;
                    else
                        return minRightBegin;
                } else {
                    if (j == 0)
                        iMax = i - 1;
                    else if (i == 0)
                        iMin = i + 1;
                    else if (nums1[i - 1] > nums2[j - 1])
                        iMax = i - 1;
                    else
                        iMin = i + 1;
                }
            }
    
            return -999;
        }
    }
    
    public class _4MedianOfTwoSortedArrays {
    
        public static void main(String[] argv) {
            int[] nums1 = {1, 3, 4};
            int[] nums2 = {2, 5, 8, 10};
    
            Solution solution = new Solution();
            double result = solution.findMedianSortedArrays(nums1, nums2);
            System.out.println(result);
        }
    }
  • 相关阅读:
    k8s 存活探针(健康检查)
    数据库CPU 100%处理记录
    zabbix 批量安装+自动注册
    Docker 学习目录
    ubuntu18启动zabbix-agent失败/故障记录
    使用Docker构建企业Jenkins CI平台
    记一次服务被黑处理过程
    ELK数据迁移,ES快照备份迁移
    脚本监控服务状态 微信-钉钉告警
    邮箱附件脚本
  • 原文地址:https://www.cnblogs.com/fly2wind/p/9993605.html
Copyright © 2011-2022 走看看