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. ffprobe使用具体解释

    夹 1. 语法 2. 描写叙述 3. 选项 3.1 流指示符 3.2 通用选项 3.3 音视频选项 3.4 主选项 4. 写入器 4.1 默认值 4.2 compact, csv 4.3 flat 4 ...

  2. jdk和jre是什么?都有什么用?(转帖)

    jdk和jre是什么?都有什么用?(转帖) 文章分类:Java编程 大家肯定在安装JDK的时候会有选择是否安装单独的jre,一般都会一起安装,我也建议大家这样做.由于这样更能帮助大家弄清楚它们的差别: ...

  3. Btrace是一个实时监控工具

    http://blog.csdn.net/gzh0222/article/details/9731031 Btrace是一个实时监控工具,可以无需修改应用代码(事实上它修改了字节码),来达到不可告人的 ...

  4. Android界面的View以及ViewGroup的区别

    因为这个问题会经常成为面试的热点,所以我们来谈谈View以及ViewGroup的区别. 先看看View及ViewGroup类关系    Android View和ViewGroup从组成架构上看,似乎 ...

  5. iOS UIKit:TableView之表格创建(1)

    Table View是UITableView类的实例对象,其是使用节(section)来描述信息的一种滚动列表.但与普通的表格不同,tableView只有一行,且只能在垂直方向进行滚动.tableVi ...

  6. '[linux下tomcat 配置

    tomcat目录结构 bin ——Tomcat执行脚本目录 conf ——Tomcat配置文件 lib ——Tomcat运行需要的库文件(JARS) logs ——Tomcat执行时的LOG文件 te ...

  7. OpenCV 2 Computer Vision Application Programming Cookbook读书笔记

    ### `highgui`的常用函数: `cv::namedWindow`:一个命名窗口 `cv::imshow`:在指定窗口显示图像 `cv::waitKey`:等待按键 ### 像素级 * 在灰度 ...

  8. jvm - 内存结构以其解析

    可以将jvm粗略分为以下部分: Heap Memory:存储java对象. Non-Heap Memory:存储加载的class文件,以及其他meta-data信息. Other:存储java代码,j ...

  9. GCD的一点理解

    大家都知道GCD 有两种队列:一种是串行队列,一种是并发队列.什么是串行队列?串行队列就是队列中的代码块一个一个按顺序执行,每当上一个代码块执行结束后下一个代码块才会执行.打个比方,如果队列是一些首尾 ...

  10. Azure cache 的配置与应用

    最近公司的项目要是用cloud Service 所以研究了下 Azure cache 的配置与使用. 首先创建项目 第二步 配置 cache worker role (1) 点击 cache work ...