zoukankan      html  css  js  c++  java
  • Median of Two Sorted Arrays LeetCode Java

    两排序好的数组,找中位数

    描述
    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)).
    分析
    这是一道非常经典的题。这题更通用的形式是,给定两个已经排序好的数组,找到两者所有元
    素中第 k 大的元素。
    O(m + n) 的解法比较直观,直接 merge 两个数组,然后求第 k 大的元素。
    不过我们仅仅需要第 k 大的元素,是不需要“排序”这么复杂的操作的。可以用一个计数器,
    记录当前已经找到第 m 大的元素了。同时我们使用两个指针 pA 和 pB,分别指向 A 和 B 数组的第
    一个元素,使用类似于 merge sort 的原理,如果数组 A 当前元素小,那么 pA++,同时 m++;如果
    数组 B 当前元素小,那么 pB++,同时 m++。最终当 m 等于 k 的时候,就得到了我们的答案,O(k)
    时间,O(1) 空间。但是,当 k 很接近 m + n 的时候,这个方法还是 O(m + n) 的。
    有没有更好的方案呢?我们可以考虑从 k 入手。如果我们每次都能够删除一个一定在第 k 大元
    素之前的元素,那么我们需要进行 k 次。但是如果每次我们都删除一半呢?由于 A 和 B 都是有序
    的,我们应该充分利用这里面的信息,类似于二分查找,也是充分利用了“有序”。
    假设 A 和 B 的元素个数都大于 k/2,我们将 A 的第 k/2 个元素(即 A[k/2-1])和 B 的第 k/2
    个元素(即 B[k/2-1])进行比较,有以下三种情况(为了简化这里先假设 k 为偶数,所得到的结
    论对于 k 是奇数也是成立的):
    • A[k/2-1] == B[k/2-1]
    • A[k/2-1] > B[k/2-1]
    • A[k/2-1] < B[k/2-1]
    如果 A[k/2-1] < B[k/2-1],意味着 A[0] 到 A[k/2-1 的肯定在 A ∪ B 的 top k 元素的范围
    内,换句话说,A[k/2-1 不可能大于 A ∪ B 的第 k 大元素。留给读者证明。
    因此,我们可以放心的删除 A 数组的这 k/2 个元素。同理,当 A[k/2-1] > B[k/2-1] 时,可
    以删除 B 数组的 k/2 个元素。
    当 A[k/2-1] == B[k/2-1] 时,说明找到了第 k 大的元素,直接返回 A[k/2-1] 或 B[k/2-1]
    即可。
    因此,我们可以写一个递归函数。那么函数什么时候应该终止呢?
    • 当 A 或 B 是空时,直接返回 B[k-1] 或 A[k-1];
    • 当 k=1 是,返回 min(A[0], B[0]);
    • 当 A[k/2-1] == B[k/2-1] 时,返回 A[k/2-1] 或 B[k/2-1]

    代码:

     1 public class Median {
     2 
     3     public static void main(String[] args) {
     4         int[] A= {2,3,5};
     5         int[] B= {4,5,6};
     6         int m=A.length;
     7         int n=B.length;
     8         int total = m + n;
     9         if(total%2==1)        //判奇偶
    10         System.out.println( find_kth(A, m, B, n, total / 2 + 1));   //奇数
    11         else
    12         System.out.println((find_kth(A, m, B, n, total / 2) + 
    find_kth(A, m, B, n, total / 2 + 1)) / 2);
    //偶数,中间位如果是偶数要除以2
    13 } 14 private static double find_kth(int A[], int m, int B[], int n, int k) { 15 if (m > n) return find_kth(B, n, A, m, k); //m,n大小相反,则发一下 16 if (m == 0) return B[k - 1]; //A[0]、B[0] k=2 17 if (k == 1) return Math.min(A[0], B[0]); 18 //将K分成两部分 19 int pa = Math.min(k / 2, m), pb = k - pa; 20 if (A[pa - 1] < B[pb - 1]) { 21 int[] Apa=new int[m-pa]; 22 for(int i=0;i<m-pa;i++) { 23 Apa[i]=A[pa+i]; 24 } 25 return find_kth(Apa, m - pa, B, n, k - pa); 26 } 27 else if (A[pa - 1] > B[pb - 1]) { 28 int[] Bpb=new int[n-pb]; 29 for(int i=0;i<n-pb;i++) { 30 Bpb[i]=B[pa+i]; 31 } 32 33 return find_kth(A, m, Bpb, n - pb, k - pb); 34 }else 35 return A[pa - 1]; 36 } 37 }
  • 相关阅读:
    python--脚本传参与shell脚本传参(位置参数)
    python--一起来盖个时间戳!!
    python--多线程的应用
    python-局域网内实现web页面用户端下载文件,easy!
    java初始化顺序
    java List<String>的初始化 的一个小问题
    java.util.Queue用法
    C#中的struct(结构)为值类型,struct类型全接触
    Java 实例
    git还原某个特定的文件到之前的版本
  • 原文地址:https://www.cnblogs.com/ncznx/p/9163358.html
Copyright © 2011-2022 走看看