1. 程式人生 > >LeetCode-Median of sorted array(2)

LeetCode-Median of sorted array(2)

#include
#include
#include
#include 

using namespace std;

class Solution {
public:
/*		取A[k / 2] B[k / 2] 比較,
		如果 A[k / 2] > B[k / 2] 那麼,所求的元素必然不在B的前k / 2個元素中(證明反證法)
		反之,必然不在A的前k / 2個元素中,於是我們可以將A或B數列的前k / 2元素刪去,求剩下兩個數列的
		k - k / 2小元素,於是得到了資料規模變小的同類問題,遞迴解決
		如果 k / 2 大於某數列個數,所求元素必然不在另一數列的前k / 2個元素中,同上操作就好。
		*/
	double findk(vector& nums1, int sk1, vector& nums2, int sk2, int k) {
		//向量不知道如何擷取部分,使用sk表明起始位置
		//因此長度的計算也變化了
		int m = nums1.size() - sk1;
		int n = nums2.size() - sk2;
		//保證 m>n 可以在後面只需要判斷m是否為0,以及求k的中間值時只考慮m是否不夠長
		if (m > n) return(findk(nums2, sk2, nums1, sk1, k));
		if (m == 0) return nums2[sk2 + k - 1];
		if (k == 1) {
			return min(nums1[sk1], nums2[sk2]);
		}
		int k1 = min(k / 2, m);
		int k2 = k - k1;
		//使用反證法思考比較容易想通
		if (nums1[sk1+k1-1] < nums2[sk2+k2-1]) {
			return findk(nums1, sk1 + k1, nums2, sk2, k - k1);
		}
		else if (nums1[sk1+k1-1] > nums2[sk2+k2-1]) {
			return findk(nums1, sk1, nums2, sk2+k2 , k - k2);
		}
		//nums1與nums2的值相等
		else {
			return nums1[k1-1];
		}
	}
	double findMedianSortedArrays(vector& nums1, vector& nums2) {
		double result;
		int m = nums1.size();
		int n = nums2.size();
		int total = m + n;
		//判斷total奇偶
		if (total & 1) {
			result = findk(nums1, 0, nums2, 0, total / 2 + 1);
		}
		else {
			result = findk(nums1, 0, nums2, 0, total / 2) + findk(nums1, 0, nums2, 0, total / 2 + 1);
			result = result / 2.0;
		}
		return result;
	}
};
void main(void)
{
	Solution sol;
	int a[] = { 1,2 };
	int b[] = { 1,2 };
	int len1 = sizeof(a) / sizeof(a[0]);
	int len2 = sizeof(b) / sizeof(b[0]);
	//vector nums1;
	//vector nums2;
	vector nums1(&a[0], &a[len1]);
	vector nums2(&b[0], &b[len2]);
	double result;
	result = sol.findMedianSortedArrays(nums1, nums2);
	cout << result << endl;
	system("pause");
}