LeetCode(3) || Median of Two Sorted Arrays

题记

之前做了3题,感觉难度一般,没想到突然来了这道比较难的,星期六花了一天的时间才做完,可见以前基础太差了。

题目内容

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)).

解题思路

  • 题目大致意思,有两个已经有序的数组A和B,他们的长度分别是m和n,现在要求获取两个数组的中位数且计算复杂度在O(log(m+n)).
  • 题目意思比较简单,咋一想很好做么,但是考虑到时间复杂度O(log(m+n))的限制就略微有点困难了。
  • 此题的难点主要在两个,一是计算复杂度,二是需要考虑很多边界情况,我在解题中就差点被淹没在无穷的边界情况中。
  • 解此题我分别使用了三种方法,分别对应三种计算复杂度,O(nlog(n)),O(n),以及O(n)
    • 第一种方法O(nlog(n))是最简单,大多数人使用的,即将数组A和数组B合并成数组C,对C进行排序再求中位数。按理说这样复杂度应该不符合题目的要求的,但是我抱着不死心的态度去LeetCode尝试了下,没想到就通过了。由此可见,LeetCode的运算时间并没有想象中的那么严格。
    • 第二种方法O(n+m)需要进行一次遍历,在遍历的过程中,比较A[k]和B[i],以从小到大顺序为例,如果A[k]<B[i]则K++,否则i++。一直到k+i达到中位数的要求。此算法的难度在于需要考虑多种边界条件。
    • 第三种方法O(log(m+n)),其实看到这个复杂度第一个反应就是对半查找,尝试了好久并未成功,后来才觉悟其实应该K值查找方法。算法内容大致如下:
      • 判断中位数的类型,即m+n若为奇数,则查找第(m+n)/2个数,否则查找第(m+n)/2和第(m+n)/2+1个数。需要考虑数组为空的情况。
      • 此时开始K值查找:

      • K值查到其实就是查找第K个值的过程分解为查找第Min(K/2,m)和K-Min(K/2,m)两步,然后再递归进行下去。所以计算复杂度在O(log(m+n)).
      • 另外需要注意的是还需要考虑几种边界条件:
        • K=1时候,返回Min(A[0],B[0])
        • m=0时候,返回B[k-1]
        • m>n时候,需要互换数组A和数组B的位置。

解题方法

方法1:计算复杂度O(n*log(n))

 public class Solution {
public double findMedianSortedArrays(int A[], int B[]) {
int m = A.length;
int n = B.length;
int[] C = new int[m+n];
double median = 0;
System.arraycopy(A, 0, C, 0, A.length);
System.arraycopy(B, 0, C, A.length, B.length);
Arrays.sort(C); if ( (m + n) % 2 == 0 ) {
median = (double)(C[(m+n)/2]+C[(m+n)/2-1])/2.0;
}else{
median = C[(m+n-1)/2];
} return median;
}
}

方法2:计算复杂度O(n)

 public class Solution {
public double findMedianSortedArrays(int A[], int B[]) {
int m = A.length;
int n = B.length;
int medianIndex1 = (m + n) % 2 == 0 ? (m+n)/2-1 :(m+n-1)/2;
int medianIndex2 = (m + n) % 2 == 0 ? (m+n)/2 :(m+n-1)/2;
int travelA = 0;
int travelB = 0;
double median = 0;
double median1 = 0;
double median2 = 0;
if ( m == 0 ){
return n % 2 == 0 ? (double)(B[n/2]+B[n/2-1])/2:B[(n-1)/2];
} if( n == 0 ){
return m % 2 == 0 ? (double) (A[m/2]+A[m/2-1])/2:A[(m-1)/2];
} for(int i = 0; i <= medianIndex2;i++){
boolean flagA = true;
if ( travelA < m && travelB < n){
if(A[travelA] >= B[travelB]){
flagA = false;
}else{
flagA = true;
}
}else if ( travelA >= m){
flagA = false;
}else{
flagA = true;
} if (flagA){
if ( i == medianIndex1 ){
median1 = A[travelA];
} if ( i == medianIndex2 ){
median2 = A[travelA];
}
travelA++;
}else{
if ( i == medianIndex1 ){
median1 = B[travelB];
} if ( i == medianIndex2 ){
median2 = B[travelB];
}
travelB++;
}
} if ( (m + n) % 2 == 0){
median = (double) (median1 + median2)/2;
}else{
median = median1;
} return median;
}
}

方法3:计算复杂度O(log(m+n))

    /**
* int A[] B[] ,数组A和数组B.
* int startA startB,子数组指针,子数组起始位置.
* int K, 需要查找的第K个值
* */
public double findKthNum(int A[],int startA,int B[],int startB, int k){
//获取数组A和数组B的子数组的数组长度
int m = A.length - startA;
int n = B.length - startB;
//假设数组A短于数组B,否则数组A和数组B互换位置。
if ( m > n){
return findKthNum(B,startB,A,startA,k);
}
//数组A为空,第K个值从数组B的子串中获取
if ( m == 0 ){
return B[startB+k-1];
}
//只获取第一个数组,在数组A和数组B的子数组的第一个元素选择
if ( k == 1 ){
return A[startA] > B[startB] ? B[startB] : A[startA];
}
//将K值查找,分为min(k/2,m)和K-min(k/2,m)两步,考虑K/2>m这种情况
int newK = Math.min(k/2,m);
int leftK = k - newK; if ( A[startA+newK-1] < B[startB+leftK-1] ){
//数组A的子数组的前newK个元素都在K值范围内,过滤这new个元素继续查找第leftK个值
return findKthNum(A,startA+newK,B,startB,leftK);
}else if (A[startA+newK-1] > B[startB+leftK-1]){
//数组B的子数组的前leftK个元素都在K值范围内,过滤这leftK个元素继续查找第k-leftK个值
return findKthNum(A,startA,B,startB+leftK,k-leftK);
}else{
//如果相等,则说明找到中位数
return A[startA+newK-1];
}
} public double findMedianSortedArrays(int A[], int B[]) {
int m = A.length;
int n = B.length;
if ( m == 0 ){
//数组A为空,则在数组B内直接查找中位数
return n % 2 == 0 ? (double)(B[n/2]+B[n/2-1])/2:B[(n-1)/2];
} if( n == 0 ){
//数组B为空,则在数组A内直接查找中位数
return m % 2 == 0 ? (double) (A[m/2]+A[m/2-1])/2:A[(m-1)/2];
} if ( (m + n) %2 != 0){
//m+n为奇数,查找第(m+n)/2+1个数
return findKthNum(A,0,B,0,(m+n)/2+1);
}else{
//m+n为偶数,查找第(m+n)/2合(m+n)/2+1个数
return ((double) (findKthNum(A,0,B,0,(m+n)/2) + findKthNum(A,0,B,0,(m+n)/2+1)))/2;
}
}

LeetCode(3) || Median of Two Sorted Arrays的更多相关文章

  1. 【算法之美】求解两个有序数组的中位数 — leetcode 4. Median of Two Sorted Arrays

    一道非常经典的题目,Median of Two Sorted Arrays.(PS:leetcode 我已经做了 190 道,欢迎围观全部题解 https://github.com/hanzichi/ ...

  2. LeetCode 4 Median of Two Sorted Arrays (两个数组的mid值)

    题目来源:https://leetcode.com/problems/median-of-two-sorted-arrays/ There are two sorted arrays nums1 an ...

  3. Leetcode 4. Median of Two Sorted Arrays(二分)

    4. Median of Two Sorted Arrays 题目链接:https://leetcode.com/problems/median-of-two-sorted-arrays/ Descr ...

  4. LeetCode 4. Median of Two Sorted Arrays & 归并排序

    Median of Two Sorted Arrays 搜索时间复杂度的时候,看到归并排序比较适合这个题目.中位数直接取即可,所以重点是排序. 再来看看治阶段,我们需要将两个已经有序的子序列合并成一个 ...

  5. 第三周 Leetcode 4. Median of Two Sorted Arrays (HARD)

    4. Median of Two Sorted Arrays 给定两个有序的整数序列.求中位数,要求复杂度为对数级别. 通常的思路,我们二分搜索中位数,对某个序列里的某个数 我们可以在对数时间内通过二 ...

  6. Leetcode 4. Median of Two Sorted Arrays(中位数+二分答案+递归)

    4. Median of Two Sorted Arrays Hard There are two sorted arrays nums1 and nums2 of size m and n resp ...

  7. LeetCode 004 Median of Two Sorted Arrays

    题目描述:Median of Two Sorted Arrays There are two sorted arrays A and B of size m and n respectively. F ...

  8. leetcode 4. Median of Two Sorted Arrays

    https://leetcode.com/problems/median-of-two-sorted-arrays/ There are two sorted arrays nums1 and num ...

  9. leetcode之 median of two sorted arrays

    这是我做的第二个leetcode题目,一开始以为和第一个一样很简单,但是做的过程中才发现这个题目非常难,给人一种“刚上战场就踩上地雷挂掉了”的感觉.后来搜了一下leetcode的难度分布表(leetc ...

随机推荐

  1. android 76 使用get post方式提交数据

    get方式: package com.itheima.getmethod; import java.io.InputStream; import java.net.HttpURLConnection; ...

  2. bitset使用

    17.10使用序列1.2.3.5.8.13.21初始化一个bitset,将这些位置置位.对另一个bitset进行默认初始化,并编写一小段程序将其恰当的位置位. #include<iostream ...

  3. 百度地图BMap API实例

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...

  4. DATABASE LINK 的查看、创建与删除

    1.查看dblink SELECT OWNER,OBJECT_NAME FROM DBA_OBJECTS WHERE OBJECT_TYPE='DATABASE LINK'; 或者 SELECT * ...

  5. ionic 项目分享【转】

    写在文章前:由于最近研究ionic框架,深感这块的Demo寥寥可数,而大家又都藏私,堂堂天朝,何时才有百家争鸣之象,开源精神吾辈当仁不让! 由于昨晚找资料太匆匆 忘记出处了,记得是在http://bb ...

  6. 搭建linux环境下jenkins可移植环境

    1:背景 项目领域:android. 项目需求为:建立一个网站用于产品经理(以下称为PM)配置该apk所需服务插件,打包出包(包含:apk,文档,demo等等)给厂商并且记录打包出包等信息. 项目设计 ...

  7. Asp.Net MVC Ajax

    将ASP.NET MVC中的form提交改为ajax提交 在ASP.NET MVC视图中通过 @using (Html.BeginForm()) 产生的是form表单提交代码,可以用javascrip ...

  8. javascript 动态操作Html

    <html> <body> <p>aaaaa</p> <input type="button" value="con ...

  9. Play - js/css concatenation & minify

    1. Css We’ll use LESS CSS, all less sources are defined in the app/assets, and they will be compiled ...

  10. JS获取页面上所有input

    for (var i = 0; i < document.getElementsByTagName("input").length; i++) { if (document. ...