zoukankan      html  css  js  c++  java
  • 【leetcode】 6.Median of Two Sorted Arrays

    There are two sorted arrays A and B 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)).

    1、如果把A和B合并成C,再取中位数。复杂度应该是O(m+n),不满足要求。

    2、要清楚的一个概念是:如果(m+n)为偶数,中位数应该是(m+n)个数排序后,位于中间的两个数的加和除以2.0。

    3、没有思路……

    用了这篇:http://www.cnblogs.com/lautsie/p/3183086.html 里提供的解法,
    主要算法参考:http://www2.myoops.org/course_material/mit/NR/rdonlyres/Electrical-Engineering-and-Computer-Science/6-046JFall-2005/30C68118-E436-4FE3-8C79-6BAFBB07D935/0/ps9sol.pdf

    思路:若(m+n)为奇数,只需找到一个中位数即为所求解;
       若(m+n)为偶数,找到第一个中位数后还应再找第二个,加和除以2.0。
      寻找第一个中位数时,先在数组A中寻找中位数,如果找不到再在数组B中寻找。
      findMedFromFirstArray寻找第一个中位数的思路:total表示第一个中位数之前应该有几个数字,在A中用二分查找A[mid], idx=total-mid,表示如果此时的A[mid]是第一个中位数的话,B中应该有且仅有idx个数小于A[mid],即B[idx] <= A[mid] && A[mid] <= B[idx + 1] ,这是在A中找到第一个中位数的终止条件。不满足这个终止条件,则需调整la和ra,取新的mid,作相同的判断。
    (idx < 0 && (idx + 1) >= 0 && A[mid] <= B[idx + 1]) 的情况是:idx=-1 A[mid]<=B[0]
      在二分查找的同时要注意idx的取值应该是有意义的。如果没有意义也应该相应调整la和ra。

      找到第一个中位数A[mid]后,如(m+n)为偶,需要找第二个中位数,第二个中位数应该是A[mid+1] 及B[total+1-mid]中较小的一个。total+1表示第二个中位数之前应该有几个数字。如果第一个中位数在B数组中,也是一样的,所以不妨把第一个中位数所在的数组命名为A。这就是findMed2的思路。

    class Result
    {
        public int[] array;
        public int index;
    }
     
    public class Solution {
        public double findMedianSortedArrays(int A[], int B[]) {
            // Start typing your Java solution below
            // DO NOT write main() function
             
            // special cases
            if (A.length == 0){
                if (B.length % 2 == 0)
                {
                    return (B[B.length / 2 - 1] + B[B.length / 2]) / 2.0;
                }
                else
                {
                    return B[B.length / 2];
                }
            }
            else if (B.length == 0)
            {
                if (A.length % 2 == 0)
                {
                    return (A[A.length / 2 - 1] + A[A.length / 2]) / 2.0;
                }
                else
                {
                    return A[A.length / 2];
                }
            }
            else if (A.length == 1 && B.length == 1)
            {
                return (A[0] + B[0]) / 2.0;
            }
     
            Result r = findMedFromFirstArray(A, B);
            if (r.index == Integer.MIN_VALUE){
                r = findMedFromFirstArray(B, A);
            }
            if (( A.length + B.length) % 2 == 0) // need to find med2
            {
                int med2 = findMed2(r, A, B);
                return (r.array[r.index] + med2) / 2.0;
            }
            else
            {
                return r.array[r.index];
            }
     
        }
     
        private Result findMedFromFirstArray(int A[], int B[])
        {
            int la = 0;
            int ra = A.length - 1;
            int total = 0;
            if (( A.length + B.length) % 2 == 0)
            {
                total = (A.length + B.length)/2 - 2;
            }
            else
            {
                total = (A.length + B.length)/2 - 1;
            }
            while (la <= ra)
            {
                int mid = (la + ra) / 2;
                int idx =  total - mid;
     
                if ((idx < 0 && (idx + 1) >= 0 && A[mid] <= B[idx + 1]) ||
                        (idx >= 0 && idx < B.length && idx + 1 >= B.length && B[idx] <= A[mid]) ||
                        (idx >= 0 && idx + 1 < B.length && B[idx] <= A[mid] && A[mid] <= B[idx + 1]))
                {
                        Result r = new Result();
                        r.index = mid;
                        r.array = A;
                        return r;
                }
                if (idx >= B.length)
                {
                    la = mid+1;
                }
                else if (idx < 0)
                {
                    ra = mid-1;
                }
                else if (B[idx] > A[mid])
                {
                    la = mid + 1;
                }
                else
                {
                    ra = mid - 1;
                }
            }
            Result r = new Result();
            r.index = Integer.MIN_VALUE; // this means not find
            r.array = A;
            return r;
        }
         
        private int findMed2(Result r, int ArrayA[], int ArrayB[])
        {
            int target1 = Integer.MAX_VALUE;
            int target2 = Integer.MAX_VALUE;
            int[] A = ArrayA;
            int[] B = ArrayB;
            if (r.array == B)
            {
                A = ArrayB;
                B = ArrayA;
            }
            {
                if (r.index + 1 < A.length)
                {
                    target1 = A[r.index + 1];
                }
                int idx = ( A.length + B.length) / 2 - 2 - r.index + 1;
                if (idx >= 0 && idx < B.length)
                {
                    target2 = B[idx];
                }
                 
                if (target1 < target2)
                {
                    return target1;
                }
                else
                {
                    return target2;
                }
            }
        }
             
    }
    

      

  • 相关阅读:
    谈谈关于MVP模式中V-P交互问题
    Delphi MVC模 2
    Delphi MVC模式 1
    Java长整除问题
    Java中Scanner类的简单用法
    Java中throw和throws的区别
    Java必须掌握的运算符
    Java编程多重循环
    Java实现三种简单的排序
    使用Java向properties存数据
  • 原文地址:https://www.cnblogs.com/guozhiguoli/p/3347377.html
Copyright © 2011-2022 走看看