• 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 };
  • 相关阅读:
    Kinect 开发 —— 硬件设备解剖
    Kinect 开发 —— 引言
    (转)OpenCV 基本知识框架
    OpenCV —— 摄像机模型与标定
    OpenCV —— 跟踪与运动
    OpenCV —— 图像局部与分割(二)
    OpenCV —— 图像局部与部分分割(一)
    OpenCV —— 轮廓
    OpenCV —— 直方图与匹配
    OpenCV —— 图像变换
  • 原文地址:https://www.cnblogs.com/sixue/p/3972690.html
Copyright © 2020-2023  润新知