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 ...
随机推荐
- hdu 4773 Problem of Apollonius
莫名其妙就AC了-- 圆的反演-- 神马是反演? 快去恶补奥数-- #include<iostream> #include<map> #include<string> ...
- MVC Controller return 格式
所看到的Action都是return View();我们可以看作这个返回值用于解析一个aspx文件.而它的返回类型是ActionResult如 public ActionResult Index() ...
- 深入了解Angularjs指令中的ngModel
关于AngularJs的指令的知识学习,请参考... 这次我们接上次没讲完的知识继续. 前端人员在设计表单逻辑时, 在大部分情况下,我们需要为表单定义很多指令, 比如比较两个input内的值是否相同, ...
- Visual Studio2012 Lua插件--BabeLua
之前,找了好久VS2012的Lua插件,没有找到. 今天在http://www.cocoachina.com/bbs/read.php? tid-205043.html 看到了.cocos2dx-qu ...
- Java经典封装JDBC模板(充分体现面向对象思想)(转)
程序清单一览 bean类 package com.software.usermanager.bean; public class Users { private String id; private ...
- careercup-数组和字符串1.5
1.5 利用字符重复出现的次数,编写一个方法,实现基本的字符串压缩功能.比如,字符串”aabcccccaaa“会变成”a2b1c5a3“.若”压缩“后的字符串没有变短,则返回原先的字符串. 类似 le ...
- JAVA格式化时间日期
JAVA格式化时间日期 import java.util.Date; import java.text.DateFormat; /** * 格式化时间类 * DateFormat.FULL = 0 * ...
- 内核增加支持yaffs2错误问题汇总
Q1: fs/yaffs2/yaffs_mtdif2.c:xxx: error: 'struct xxx1' has no member named 'fun_xxx' A1:比对fun_xxx和st ...
- JDK1.8聚合操作
在java8 JDK包含许多聚合操作(如平均值,总和,最小,最大,和计数),返回一个计算流stream的聚合结果.这些聚合操作被称为聚合操作.JDK除返回单个值的聚合操作外,还有很多聚合操作返回一个c ...
- JQuery Datatables(一)
最近项目中用了Bootstrap的样式风格,控件用了JQuery Datatables,主要有几下几点目标: 实现BootStrap风格的table,使用Ajax获取数据,并有勾选项 可以实现全选,单 ...