leecode algo4: Median of Two Sorted Arrays (Java)

leetcode algo4:Median of Two Sorted Arrays

題目: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)).

實現思想:

上述問題是求兩個有序數組的中位數。我們首先想到的方法是:合併兩個有序數組得到一個有序數組,算法複雜度爲:O(m+n),然後直接輸出中位數(其實我們在合併的過程中就可以輸出中位數),但是這個方法複雜度達不到要求。

算法複雜度既然要達到log級別,很大可能上需要利用分治法,而在這一題中如何運用分治法呢?我們有這樣一個直觀上的認識:我們分別取nums1[k/2]和nums2[k/2](k爲中位數的序,從1計數;假設nums1[k/2]和nums2[k/2]都存在),如果nums1[k/2]<nums2[k/2],那麼中位數肯定不在nums1[0]至nums1[k/2]中。通過這個直觀上的認識,我們是不是想到了什麼?我們利用上述的思想每次可以在兩個數組的某一個數組中去掉k*(0.5^n)個元素,直至找到中位數。下面可以通過看看代碼瞭解一下具體的邏輯(leetcode 提交通過, Run Time:6ms)。

package algo4;

public class Solution {

	public static void main(String[] args) {
		Solution s = new Solution();
		int[] nums1 = {5, 23, 222, 23232};
		int[] nums2 = {1, 2, 1212, 2222};
		System.out.println(s.findMedianSortedArrays(nums1, nums2));
	}

	public double findMedianSortedArrays(int[] nums1, int[] nums2) {
		if(nums1.length == 0) {
			if(nums2.length % 2 == 0) {
				return (nums2[nums2.length/2 - 1] + nums2[nums2.length/2])/2d;
			} else {
				return nums2[nums2.length/2];
			}
		}
		if(nums2.length == 0) {
			if(nums1.length % 2 == 0) {
				return (nums1[nums1.length/2 - 1] + nums1[nums1.length/2])/2d;
			} else {
				return nums1[nums1.length/2];
			}
		}
		int total = nums1.length + nums2.length;
		if(total % 2 == 0) {
			return (findkth(nums1, 0, nums2, 0, total/2) + findkth(nums1, 0, nums2, 0, total/2 + 1))/2d;
		} else {
			return findkth(nums1, 0, nums2, 0, total/2 + 1);
		}
	}
	
	/**
	 * @param nums1 : 有序數組1
	 * @param s1 : 有序數組1的起始index(前面的數據都被排除存在中位數的可能了)
	 * @param nums2 : 有序數組2
	 * @param s2:有序數組2的起始index
	 * @param k:中位數在兩個有序數組的剩餘部分(起始index後)上的序
	 */
	private double findkth(int[] nums1, int s1, int[] nums2, int s2, int k) {
		if(s1 == nums1.length) {
			return nums2[s2 + k - 1];
		}
		if(s2 == nums2.length) {
			return nums1[s1 + k - 1];
		}
		if(k == 1) {
			if(nums1[s1] < nums2[s2]) {
				return nums1[s1];
			} else {
				return nums2[s2];
			}
		}
		
		if(nums1.length - s1 < k/2) {
			return findkth(nums1, s1, nums2, s2 + k/2, k%2 == 0 ? k/2 : k/2 + 1);
		}
		if(nums2.length - s2 < k/2) {
			return findkth(nums1, s1 + k/2, nums2, s2, k%2 == 0 ? k/2 : k/2 + 1);
		}
		
		if(nums1[k/2 + s1 - 1] < nums2[k/2 + s2 - 1]) {
			return findkth(nums1, s1 + k/2, nums2, s2, k%2 == 0 ? k/2 : k/2 + 1);
		} else if(nums1[k/2 + s1 - 1] > nums2[k/2 + s2 - 1]) {
			return findkth(nums1, s1, nums2, s2 + k/2, k%2 == 0 ? k/2 : k/2 + 1);
		} else {
			if(k % 2 == 0) {
				return nums1[k/2 + s1 - 1];
			} else {
				if(nums1[k/2 + s1] < nums2[k/2 + s2]) {
					return nums1[k/2 + s1];
				} else {
					return nums2[k/2 + s2];
				}
			}
		}
	}
	/*
	private int binarySearch(int[] nums, int v) {
		int begin = 0, end = nums.length - 1, medianIndex;
		while(true) {
			if(begin == end) {
				return begin + 1;
			}
			medianIndex = (begin + end)/2;
			if(nums[medianIndex] < v) {
				begin = medianIndex + 1;
			} else if(nums[medianIndex] > v) {
				end = medianIndex;
			} else {
				return medianIndex + 1;
			}
		}
	}
	 */
}



發佈了48 篇原創文章 · 獲贊 54 · 訪問量 26萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章