LeetCode(3) || Median of Two Sorted Arrays
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的更多相关文章
- 【算法之美】求解两个有序数组的中位数 — leetcode 4. Median of Two Sorted Arrays
一道非常经典的题目,Median of Two Sorted Arrays.(PS:leetcode 我已经做了 190 道,欢迎围观全部题解 https://github.com/hanzichi/ ...
- LeetCode 4 Median of Two Sorted Arrays (两个数组的mid值)
题目来源:https://leetcode.com/problems/median-of-two-sorted-arrays/ There are two sorted arrays nums1 an ...
- Leetcode 4. Median of Two Sorted Arrays(二分)
4. Median of Two Sorted Arrays 题目链接:https://leetcode.com/problems/median-of-two-sorted-arrays/ Descr ...
- LeetCode 4. Median of Two Sorted Arrays & 归并排序
Median of Two Sorted Arrays 搜索时间复杂度的时候,看到归并排序比较适合这个题目.中位数直接取即可,所以重点是排序. 再来看看治阶段,我们需要将两个已经有序的子序列合并成一个 ...
- 第三周 Leetcode 4. Median of Two Sorted Arrays (HARD)
4. Median of Two Sorted Arrays 给定两个有序的整数序列.求中位数,要求复杂度为对数级别. 通常的思路,我们二分搜索中位数,对某个序列里的某个数 我们可以在对数时间内通过二 ...
- 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 ...
- 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 ...
- leetcode 4. Median of Two Sorted Arrays
https://leetcode.com/problems/median-of-two-sorted-arrays/ There are two sorted arrays nums1 and num ...
- leetcode之 median of two sorted arrays
这是我做的第二个leetcode题目,一开始以为和第一个一样很简单,但是做的过程中才发现这个题目非常难,给人一种“刚上战场就踩上地雷挂掉了”的感觉.后来搜了一下leetcode的难度分布表(leetc ...
随机推荐
- ffprobe使用具体解释
夹 1. 语法 2. 描写叙述 3. 选项 3.1 流指示符 3.2 通用选项 3.3 音视频选项 3.4 主选项 4. 写入器 4.1 默认值 4.2 compact, csv 4.3 flat 4 ...
- jdk和jre是什么?都有什么用?(转帖)
jdk和jre是什么?都有什么用?(转帖) 文章分类:Java编程 大家肯定在安装JDK的时候会有选择是否安装单独的jre,一般都会一起安装,我也建议大家这样做.由于这样更能帮助大家弄清楚它们的差别: ...
- Btrace是一个实时监控工具
http://blog.csdn.net/gzh0222/article/details/9731031 Btrace是一个实时监控工具,可以无需修改应用代码(事实上它修改了字节码),来达到不可告人的 ...
- Android界面的View以及ViewGroup的区别
因为这个问题会经常成为面试的热点,所以我们来谈谈View以及ViewGroup的区别. 先看看View及ViewGroup类关系 Android View和ViewGroup从组成架构上看,似乎 ...
- iOS UIKit:TableView之表格创建(1)
Table View是UITableView类的实例对象,其是使用节(section)来描述信息的一种滚动列表.但与普通的表格不同,tableView只有一行,且只能在垂直方向进行滚动.tableVi ...
- '[linux下tomcat 配置
tomcat目录结构 bin ——Tomcat执行脚本目录 conf ——Tomcat配置文件 lib ——Tomcat运行需要的库文件(JARS) logs ——Tomcat执行时的LOG文件 te ...
- OpenCV 2 Computer Vision Application Programming Cookbook读书笔记
### `highgui`的常用函数: `cv::namedWindow`:一个命名窗口 `cv::imshow`:在指定窗口显示图像 `cv::waitKey`:等待按键 ### 像素级 * 在灰度 ...
- jvm - 内存结构以其解析
可以将jvm粗略分为以下部分: Heap Memory:存储java对象. Non-Heap Memory:存储加载的class文件,以及其他meta-data信息. Other:存储java代码,j ...
- GCD的一点理解
大家都知道GCD 有两种队列:一种是串行队列,一种是并发队列.什么是串行队列?串行队列就是队列中的代码块一个一个按顺序执行,每当上一个代码块执行结束后下一个代码块才会执行.打个比方,如果队列是一些首尾 ...
- Azure cache 的配置与应用
最近公司的项目要是用cloud Service 所以研究了下 Azure cache 的配置与使用. 首先创建项目 第二步 配置 cache worker role (1) 点击 cache work ...