内容:
1、利用java自带函数破解
核心思想:两个数组转list合并,由小到大重排序,数组长度奇数直接取中位数的值,为偶数则取中位数和中位数前一位两数合的一半
时间复杂度O(m+n),空间复杂度O(m+n),m和n分别为两个数组长度
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
double result = 0.0;
List<Integer> list1 = Arrays.stream(nums1).boxed().collect(Collectors.toList());
List<Integer> list2 = Arrays.stream(nums2).boxed().collect(Collectors.toList());
list1.addAll(list2);
Collections.sort(list1);
int middle = list1.size()/2;
if(list1.size()%2==1){
result = list1.get(middle);
}else{
result = (double)(list1.get(middle-1) + list1.get(middle)) / 2;
}
return result;
}
}
2、不合并数组的解法
核心思想就是分别控制两个数组的游标取元素比大小,记录每次比较的两个值,left放小值,right放大值,最后两个数组总长度为奇数就直接取right,偶数就是两数的差
时间复杂度依然是O(m+n),空间复杂度O(1),虽然时间复杂度没变,不过比上面省略了合并数组的空间+重排序的时间
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
double result = 0.0;
int nums1Index = 0,nums2Index = 0,left = 0,right = 0;
int sumLength = nums1.length + nums2.length;
int middle = sumLength / 2;
for(int i = 0;i <= middle; i++){
left = right;
if(nums1Index<nums1.length &&
(nums2.length<=nums2Index || nums1[nums1Index]<=nums2[nums2Index]) ){
right = nums1[nums1Index++];
}else{
right = nums2[nums2Index++];
}
}
if(sumLength%2==1){
result = right;
}else{
result = (double)(left+right)/2;
}
return result;
}
}
3、二分法
Ps:该解法为力扣题目进阶要求时间复杂度O(log(m+n))的解法,虽然要更复杂一些,不过算法算法,肯定是要精益求精。换句话说,上面两种的确简单,但大部分人都可以写出来,是否实用暂且不论,泯然众人矣。
时间复杂度O(log(m+n)),空间复杂度O(1)
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int sumLength = nums1.length + nums2.length;
int k = sumLength / 2 + 1;
if(sumLength % 2 == 1){
return queryK(nums1,nums2,k);
}else{
return (double)(queryK(nums1,nums2,k - 1) + queryK(nums1,nums2,k)) / 2;
}
}
public static double queryK(int[] nums1, int nums2[], int k){
int index1 = 0,index2 = 0;
while(true){
if(index1 > nums1.length - 1){
return (double)nums2[index2 + k - 1];
}
if(index2 > nums2.length - 1){
return (double)nums1[index1 + k - 1];
}
if(k==1){
return Math.min(nums1[index1],nums2[index2]);
}
int half = k / 2;
int newIndex1 = Math.min(nums1.length - 1,index1 + half - 1);
int newIndex2 = Math.min(nums2.length - 1,index2 + half - 1);
if(nums1[newIndex1] <= nums2[newIndex2]){
k -= (newIndex1 - index1 + 1);
index1 = newIndex1 + 1;
}
else{
k -= (newIndex2 - index2 + 1);
index2 = newIndex2 + 1;
}
}
}