题目:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/
答案:
1、合并排序数组
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int[] nums3= new int[nums1.length+nums2.length];
int i=0,j=0,k=0;
while (i<nums1.length && j<nums2.length){
if(nums1[i]<nums2[j]){
nums3[k++]=nums1[i++];
}else{
nums3[k++]=nums2[j++];
}
}
while (i<nums1.length){
nums3[k++] = nums1[i++];
}
while (j<nums2.length){
nums3[k++] = nums2[j++];
}
if(nums3.length%2==0){
return ((double) nums3[nums3.length/2-1]+(double) nums3[nums3.length/2])/2;
}else{
return nums3[nums3.length/2];
}
}
时间复杂度为 O(m+n),空间复杂度O(m+n) 不符合要求
2.这里得到了整个有序数组,实际上是不需要知道所有的,只需要知道中位数就行了
如果 m+n 是偶数 ,就得到 (m+n)/2 个数 和(m+n)/2+1 个数 ,也就是 坐标为(m+n)/2 -1 和 (m+n)/2
如果 m+n 是奇数,就得到 (m+n+1)/2 个数,也就是坐标为 (m+n+1)/2-1就行了
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int m = nums1.length;
int n = nums2.length;
int length = m+n;
int left = -1, right = -1;
int start1 = 0, start2 = 0;
for(int i=0;i<=length/2;i++){
left = right;
if(start1<m && (start2>=n || nums1[start1]<nums2[start2])){
right = nums1[start1++];
}else{
right = nums2[start2++];
}
}
if((length&1) == 0) return (left+right)/2.0;
return right;
}
题目时间复杂度度 还是O(m+n),控件复杂度为O(1)
3、解法2的进阶版,找第k小数,二分查找思想变种
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int length1= nums1.length;
int length2 =nums2.length;
int left = (length1+length2+1)/2;
int right = (length1+length2+2)/2;
//如果 length1+length2 为奇数,则 left 和 right 相等的,偶数才不相等
return (getK(nums1,0,length1-1,nums2,0,length2-1,left)+
getK(nums1,0,length1-1,nums2,0,length2-1,right))/2.0;
}
public int getK(int[] nums1,int start1,int end1,int[] nums2,int start2,int end2,int k){
int len1 = end1-start1+1;
int len2 = end2-start2+1;
if(len1>len2) return getK(nums2,start2,end2,nums1,start1,end1,k);
if(len1==0) return nums2[start2+k-1];
if(k==1) return Math.min(nums1[start1],nums2[start2]);
int index1 = start1 + Math.min(len1,k/2)-1;
int index2 = start2 + Math.min(len2,k/2)-1;
if(nums1[index1]>nums2[index2]){
return getK(nums1,start1,end1,nums2,index2+1,end2,k-(index2-start2+1));
}else{
return getK(nums1,index1+1,end1,nums2,start2,end2,k-(index1-start1+1));
}
}
时间复杂度 O(log(m+n)),控件复杂度为)O(1)
4.二分查找:
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int m = nums1.length;
int n = nums2.length;
if (m > n) {
return findMedianSortedArrays(nums2,nums1);
}
int iMin = 0, iMax = m;
while (iMin <= iMax) {
int i = (iMin + iMax) / 2;
int j = (m + n + 1) / 2 - i;
if (j != 0 && i != m && nums2[j-1] > nums1[i]){ // i 需要增大
iMin = i + 1;
}
else if (i != 0 && j != n && nums1[i-1] > nums2[j]) { // i 需要减小
iMax = i - 1;
}
else { // 达到要求,并且将边界条件列出来单独考虑
int maxLeft = 0;
if (i == 0) { maxLeft = nums2[j-1]; }
else if (j == 0) { maxLeft = nums1[i-1]; }
else { maxLeft = Math.max(nums1[i-1], nums2[j-1]); }
if ( (m + n) % 2 == 1 ) { return maxLeft; } // 奇数的话不需要考虑右半部分
int minRight = 0;
if (i == m) { minRight = nums2[j]; }
else if (j == n) { minRight = nums1[i]; }
else { minRight = Math.min(nums2[j], nums1[i]); }
return (maxLeft + minRight) / 2.0; //如果是偶数的话返回结果
}
}
return 0.0;
}
以时间复杂度是 O(log(min(m,n)),空间复杂度 O(1)