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

    题目

       There are two sorted arrays A and B of size m and n respectively.Find the Median of two sorted arrays.The overall run time complexity should be O(log(m+n)).

    题目分析:

       当我第一眼看见这题目时,就想到采用归并排序的方式,在两个数组上设立两个指针从头开始逐一比较。直到找到对应的元素为止。下面是自己开始写的代码:

     1 class Solution {
     2 public:
     3     
     4     double findMedianSortedArrays(int A[], int m, int B[], int n) {
     5          double result,right;
     6          int num=(n+m+1)/2;
     7          int i=0,j=0,cnt=0;
     8          
     9          while(i!=m && j!=n){
    10              if(A[i]<=B[j]){
    11                  result=A[i];
    12                  i++;
    13                  cnt++;
    14              }
    15              
    16              else{
    17                  result=B[j];                
    18                  j++;
    19                  cnt++;
    20              }
    21              
    22              if(cnt==num) {
    23                 flag=true;
    24                 break;
    25              }
    26          }
    27                   
    28          while(i!=m){
    29              if(cnt==num) break;
    30              else{
    31                  result=A[i];            
    32                  i++;
    33                  cnt++;
    34              }
    35          }
    36          
    37          while(j!=n){
    38              if(cnt==num) break;
    39              else{
    40                  result=B[j];
    41                  j++;
    42                  cnt++;
    43              }
    44          }
    45 
    46        return result;
    47     }

    但是运行之后就发现出现了错误,折腾了很久也没有想明白。后面在网上找资料,才明白自己犯了一个最基本的错误,没有理解Median的含义。当Array的个数是奇数时,Median的值是最中间的一个。当它是偶数时,Median的值是n/2和n/2+1上的值的平均数。

    网上的解法普遍都是一样的,看了之后发现这种解法确实很巧妙,貌似是某年考研的算法题,先记录下来。

    解题思路:

    该方法的核心是将原问题转变成一个寻找第k小的数问题(假设两个原序列升序排列),这样中位数实际上是第(m+n)/2小的数(暂不考虑偶数情形).所以只要解决了第k小的数,原问题就得以解决。

     

    首先假设数组A和B的元素个数都大于k/2,我们比较A[k/2-1]和B[k/2-1]两个元素,分别代表A和B数组的第k个元素。如果A[k/2-1]<B[k/2-1],这表示A[0]到A[k/2-1]的元素都在A和B合并之后的前k个元素中。也就是说,A[k/2-1]不可能大于两数组合并之后的第k小值,所以我们可以将其抛弃。(注意:这是该算法最核心的地方)。

    反证法:

         假设A[k/2-1]大于合并之后的第k小值,我们不妨假定为第(k+1)小值。由于A[k/2-1]小于B[k/2-1],所以B[k/2-1]至少是第(k+2)小值。但实际上,在A中至多存在k/2-1个元素小于A[k/2-1],B中至多存在k/2-1个元素A[k/2-1],所以小于A[k/2-1]的元素个数至多有k/2+k/2-2,小于k,这与A[k/2-1]是k+1的数矛盾。

     

        当A[k/2-1]>B[k/2-1]时也类似。

      当A[k/2-1]==B[k/2-1]时,则我们已经找到第k的元素,也就是这个相等的元素。将其记为m,由于A和B中分别有k/2-1个元素小于m,所以m即是第k小的数。

     

    因此总结起来就是:

    •  如果A或者B为空,则直接返回B[k-1]或者A[k-1]。
    •  如果k为1,我们只需要返回A[0]和B[0]中的较小值。
    •  如果A[k/2-1]=B[k/2-1],返回其中一个。

      代码如下:

     1 public:{
     2 
     3     dobule findKth(int A[],int m,int  B[],int n,int k){
     4          //m is equal or smaller than n
     5           if(m<n)
     6               return findKth(B,n,A,m,k);
     7           if(m==0)
     8               return B[k-1];
     9           if(k==1)
    10               return min(A[0],B[0]);
    11           
    12            int pa=min(k/2,m),pb=k-pa;
    13            if(A[pa-1]<B[pb-1])
    14                 return findKth(A+pa,m-pa,B,n,k-pa);
    15            else if(A[pa-1]>B[pb-1])
    16                 return findKth(A,m,B+pb,n-pb,k-pb);
    17            else
    18                 return A[pa-1];
    19     }
    20 
    21     dobule findMedianSortedArrays(int A[],int m,int B[],int n){
    22           int k=m+n;
    23           if(k & 0x1){
    24                 return findKth(A,m,B,n,k/2+1);
    25           }
    26           else{
    27                  return (findKth(A,m,B,n,k/2)+findKth(A,m,B,n,k/2+1))/2;
    28           }
    29     }
    30 };
  • 相关阅读:
    2019牛客暑期多校训练营(第二场)H Second Large Rectangle
    HDU -1506 Largest Rectangle in a Histogram&&51nod 1158 全是1的最大子矩阵 (单调栈)
    吉哥系列故事——完美队形II(马拉车算法)
    Theme Section
    激光雷达和毫米波雷达
    模型压缩95%:Lite Transformer,MIT韩松等人
    分布式深度学习DDL解析
    TOF摄像机可以替代Flash激光雷达吗?
    毫米波雷达分类和技术方案
    高精地图与自动驾驶(下)
  • 原文地址:https://www.cnblogs.com/sixue/p/3972690.html
Copyright © 2011-2022 走看看