题目:
- 寻找两个正序数组的中位数
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
详见:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/
思路:
本题的思路有两种,力扣上的官方也有所解读,但是我理解的是将这两种思路合并成为一种:
假设我们已经把两个数组合并了,中位数的索引位置得到的是k,相当于在这个数组中有k个元素比中位数小,而这个k值我们又很好求得(因为两个数组的数组长度都知道),所以我们只需要求得第k小的元素是哪一个或者哪两个就可以了。
在求第k小的元素时,因为已知的两个数组都是有序的,我们可以定义两个指针i和j,分别从两个数组的0位置开始遍历,如果nums1[i]<=nums2[j],遍历nums1数组,i++;如果nums2[j]<nums1[i],遍历nums2数组,j++,直到遍历到k就停止,并得到那一个数或者两个数。然后就求得中位数了。
代码:
上述思路的代码:这个代码其实还可以优化,不过为了方便大家理解,我代码就写杂了一点:
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int n= nums1.length+nums2.length;
int q,p;
if(n%2==0) {
q=n/2-1;
p=n/2;
}else {
q=p=n/2;
}
double result = this.mergeArr(nums1,nums2,q,p);
return result;
}
// 合并数组
private double mergeArr(int[] nums1, int[] nums2,int q,int p) {
// TODO Auto-generated method stub
int n = nums1.length,m=nums2.length;
if(n==0) {
return (nums2[q]+nums2[p])/2.0;
}
if(m==0) {
return (nums1[q]+nums1[p])/2.0;
}
int i=0,j=0,k=0;
int result1 = 0;
int result2 = 0;
okk:
while(i<n||j<m) {
while(nums1[i]<=nums2[j]) {
if(k==q) result1=nums1[i];
if(k==p) {
result2=nums1[i];
break okk;
}
i++;
k++;
if(i==n) {
while(j<m) {
if(k==q) result1=nums2[j];
if(k==p) {
result2=nums2[j];
break okk;
}
j++;
k++;
}
break okk;
}
}
while(nums2[j]<=nums1[i]) {
if(k==q) result1=nums2[j];
if(k==p) {
result2=nums2[j];
break okk;
}
j++;
k++;
if(j==m) {
while(i<n) {
if(k==q) result1=nums1[i];
if(k==p) {
result2=nums1[i];
break okk;
}
i++;
k++;
}
break okk;
}
}
}
return (result1+result2)/2.0;
}
}
有同学还是想合并成一个新数组,这里也给出了相应的代码
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int[] newArr = this.mergeArr(nums1,nums2);
int n= newArr.length;
double result=0;
if(n%2==0) {
result = (newArr[n/2-1]+newArr[n/2])/2.0;
}else {
result = newArr[n/2];
}
return result;
}
// 合并数组
private int[] mergeArr(int[] nums1, int[] nums2) {
// TODO Auto-generated method stub
int n = nums1.length,m=nums2.length;
if(n==0) {
return nums2;
}
if(m==0) {
return nums1;
}
int[] newArr = new int[n+m];
int i=0,j=0,k=0;
okk:
while(i<n||j<m) {
while(nums1[i]<=nums2[j]) {
newArr[k] = nums1[i];
i++;
k++;
if(i==n) {
while(j<m) {
newArr[k]=nums2[j];
j++;
k++;
}
break okk;
}
}
while(nums2[j]<=nums1[i]) {
newArr[k] = nums2[j];
j++;
k++;
if(j==m) {
while(i<n) {
newArr[k]=nums1[i];
i++;
k++;
}
break okk;
}
}
}
return newArr;
}
}