Median of Two Sorted Arrays---LeetCode進階路④
阿新 • • 發佈:2018-12-10
- 題目描述
There are two sorted arrays nums1 and nums2 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)).
You may assume nums1 and nums2 cannot be both empty.
分別有大小為m和n的有序陣列nums1和nums2。
求兩個排序陣列的中值。總的執行時複雜度應該是O(log (m+n))。
您可以假設nums1和nums2不能同時為空。
Example 1:
nums1 = [1, 3]
nums2 = [2]
The median is 2.0
Example 2:
nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5
- 思路分析:
需求是輸出兩個有序陣列的中值,想要實現很是簡單,最直接粗暴的方法是把兩個數組合並,找到相應元素,時間複雜度為O(m+n)。但題目明確要求時間複雜度需要控制在O(log(m+n)),就必須思考優化版方法啦。
小陌目前的優化方法是用尋找第k小數(因為給出的兩個陣列皆有序,則k對應(m+n)/2):
每次比較兩個陣列的第k/2個大的數:
- nums1[k/2] = nums[k/2],那麼這個數就是我們要找的第K小數
- nums1[k/2] > nums[k/2],則說明第K小數不在nums2中前k/2個元素,可排除
- nums1[k/2] < nums[k/2],與2同理,排除nums1中前k/2個元素
如此操作,每次都能排除k/2的元素(遞迴過程中,可能會出現陣列個數不到k/2的情況,並不會影響演算法,從另一個數組進行補充,多取相應元素即可)。
當k=1時,找到第K小數,結束遞迴
- 原碼附錄:
- 簡單粗暴法
class Solution { public double findMedianSortedArrays(int[] nums1, int[] nums2) { int all = nums1.length+nums2.length; int[] result = new int[all]; for(int i=0;i<all;i++){ result[i] = (i<nums1.length)?nums1[i]:nums2[i-nums1.length]; } Arrays.sort(result); return (all%2) ==1 ? result[(all-1)/2]:(double)(result[all/2]+result[all/2-1])/2; } }
- top k演算法思想
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
if((nums1.length+nums2.length)%2==0){
return (findK(nums1,0,nums1.length-1,nums2,0,nums2.length-1,(nums1.length+nums2.length)/2)
+findK(nums1,0,nums1.length-1,nums2,0,nums2.length-1,(nums1.length+nums2.length)/2+1))/2.0;
}
else{
return findK(nums1,0,nums1.length-1,nums2,0,nums2.length-1,(nums1.length+nums2.length)/2+1);
}
}
public int findK(int[] nums1,int n1,int n2,int[] nums2,int m1,int m2,int k){
int i = n2 - n1 +1;
int j = m2 - m1 +1;
if(i>j){
return findK(nums2,m1,m2,nums1,n1,n2,k);
}
if(i == 0){
return nums2[m1+k-1];
}
if(k == 1){
return Math.min(nums1[n1],nums2[m1]);
}
int mid1 = Math.min(k/2,i);
int mid2 = k - mid1;
if(nums1[n1+mid1-1]==nums2[m1+mid2-1]){
return nums1[n1+mid1-1];
}
else if(nums1[n1+mid1-1]>nums2[m1+mid2-1]){
return findK(nums1,n1,n1+mid1-1,nums2,m1+mid2,m2,k-mid2);
}
else{
return findK(nums1,n1+mid1,n2,nums2,m1,m2+mid2-1,k-mid1);
}
}
}
以下內容為可恥的自我推銷,完全可忽略(。•́ωก̀。).。
此處厚臉皮的安利小透明公眾號 林夏夏
夏夏大大的英雄夢,
就是能和最喜歡的你,
分享一道演算法題,
溫習一個程式設計上易忽視小細節,
品一份書香氤氳,
道最後一句晚安ヾ(◍°∇°◍)ノ゙