题目大意:给定两个有序数组,大小分别为m, n,求出两个数组的中间值,要求时间复杂度为O(log(m+n))。
理解:
1)题目给的两个数组中都可能存在重复元素;
2)中间值指的是:如果数组总长度为奇数,则为中间元素;如果总长度为偶数,则为中间那两个元素的均值,要求为double类型;
实现:如果数组A, B均为空,则返回0,;如果A为空,则搜索数组B;如果B为空,则搜索数组A;否则搜索A,B.
public class Solution {
public double search(int[] a, int len, boolean flag) { // 搜索A或B
int mid = (len-1) >> 1;
int i = 0;
while(i < mid) i ++;
if(flag) return a[i]*1.0;
else return 1.0*(a[i] + a[i+1]) / 2;
}
// A,B均不为空,搜索A,B
public double searchAB(int[] a, int[] b, int lena, int lenb, int len, boolean flag) {
int mid = (len-1) >> 1;
int i = 0, j = 0;
boolean tag = false; // 标记是否找到中间位置
while(i < lena && j < lenb) {
if((i + j) == mid) {
tag = true;
break;
}
else if(a[i] < b[j]) i ++;
else j ++;
}
if(tag) { // 找到中间位置
if(flag) { // 总长度为奇数,返回较小的那个值,并转为double类型
if(a[i] < b[j]) return 1.0*a[i];
else return 1.0*b[j];
}
else { // 总长度为偶数,返回较小值与其后一个元素或另一数组中i或j指的元素求平均
if(a[i] <= b[j]) {
if(i+1 < lena && a[i+1] <= b[j]) return 1.0*(a[i] + a[i+1]) / 2; // 若a[i+1]较小,则与a[i+1]之和
else return 1.0*(a[i] + b[j]) / 2; // 否则,与j所指的元素之和
}
else {
if(j+1 < lenb && b[j+1] <= a[i]) return 1.0*(b[j] + b[j+1]) / 2; // 若b[j+1]较小,则与b[j+1]之和
else return 1.0*(a[i] + b[j]) / 2; // 否则,与i所指元素之和
}
}
}
else {
if(i < lena) {
while(i < lena) {
if(i + j == mid) break;
i ++;
}
if(flag) return a[i]*1.0;
else return 1.0*(a[i] + a[i+1]) / 2;
}
else {
while(j < lenb) {
if(i + j == mid) break;
j ++;
}
if(flag) return b[j]*1.0;
return 1.0*(b[j] + b[j+1]) / 2;
}
}
}
public double findMedianSortedArrays(int A[], int B[]) {
if((A == null || A.length == 0) && (B == null || B.length == 0)) return 0; // A,B均为空
if(A == null || A.length == 0) { // B不为空
int lenb = B.length;
if(lenb % 2 == 1) { // 判断长度奇偶性
return search(B, lenb, true); // true表示为奇数
}
else return search(B, lenb, false); // false表示为偶数
}
else if(B == null || B.length == 0) { // A不为空
int lena = A.length;
if(lena % 2 == 1) return search(A, lena, true);
else return search(A, lena, false);
}
else { // A,B均不为空
int lena = A.length, lenb = B.length;
int len = lena + lenb;
if(len % 2 == 1) {
return searchAB(A, B, lena, lenb, len, true);
}
else return searchAB(A, B, lena, lenb, len, false);
}
}
}
失误:上面的方法的时间复杂度是O(m+n)。二分的方法还在探索中。。