leetcode:Median of Two Sorted Arrays

这个题目里说O(log(m+n)),还以为和严格,结果m+n时间的居然过了。。

class Solution {
public:
	double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
		double cur_num = 0;
		int count = 0;
		int medium = (nums1.size() + nums2.size()) / 2+1;
		bool is_odd = ((nums1.size() + nums2.size()) % 2 == 1);
		int itr1 = 0;
		int itr2 = 0;
		while (true) {
			int temp = 0;
			if (count == medium ) {
				break;
			}
			if (itr1 < nums1.size() && itr2 < nums2.size()) {
				if (nums1[itr1] < nums2[itr2]) {
					temp = nums1[itr1];
					itr1++;
					count++;
				}
				else {
					temp = nums2[itr2];
					itr2++;
					count++;
				}
			}
			else if (itr1 >nums1.size() && itr2>nums2.size()) {
				break;
			}
			else if (itr1 < nums1.size()) {
				temp = nums1[itr1];
				itr1++;
				count++;
			}
			else {
				temp = nums2[itr2];
				itr2++;
				count++;
			}
			//update cur_num value
			if (!is_odd && count == medium) {
				cur_num += temp;
				cur_num /= 2;
			}
			else {
				cur_num = temp;
			}
		}
		return cur_num;
	}
};


然后是想log(m+n)解法,第一想法就是取两个数组中位数比较,但是思路始终固定在来想把数组规模减半,结果怎么都做不到。

然后找答案,结果居然是把题目一般化,讲中位数条件改成第k大的数,然后将k的规模每次缩小一半。因为本题的k=(m+n)/2,所以时间复杂度是O(log(m+n))的

具体的算法就是在规模较小的数组A中去第k/2大小的数和规模较大的数组B中第k/2的数比较,如果A[k/2-1]<B[k/2-1],那么说明A的前k/2个数都比两个数组的第k个数要小,所以可以排除,同时变成从数组A[k/2]~A[k-1]和B数组中找第k/2大的数

递归终点有三种情况

1.存在空数组,那么从另外一个非空数组里取(如果输入有意义,两个空数组是不会出现的)

2.k=1,那么从两个数组取第一小的数,所以返回A[0]和B[0]中较小的

3.A[k/2-1]=B[k/2-1]那么直接返回该值

细节上其实k/2可能会大于A的数组大小,那就取其中较小的即可,如果出现这种情况其实相当于快到递归终点了,也可以单独判断重点也可以去值是取min(k/2,A.size)即可。

class Solution {
public:
	int findKth(vector<int>& nums1, vector<int>& nums2, int s1, int size1, int s2, int size2, int k) {
		//make nums1.size() <= nums2.size()
		if (size1 > size2) {
			return findKth(nums2, nums1, s2, size2, s1, size1, k);
		}
		if (size1 <= 0 && size2 <= 0) { return 0; }
		if (size1 <= 0) {
			return nums2[k - 1];
		}
		else if(size2 <= 0){
			return nums1[k - 1];
		}
		if (k == 1) {
			return nums1[s1] <= nums2[s2] ? nums1[s1] : nums2[s2];
		}
		int itr1 = k/2 < size1 ? k/2 : size1;
		int itr2 = k - itr1;
		if (nums1[s1 + itr1 - 1] < nums2[s2 + itr2 - 1]) {
			return findKth(nums1, nums2, s1 + itr1, size1 - itr1, s2, size2, k - itr1);
		}
		else if (nums1[s1 + itr1 - 1] > nums2[s2 + itr2 - 1]) {
			return findKth(nums1, nums2, s1, size1, s2 + itr2, size2 - itr2, k - itr2);
		}
		else {
			return nums1[s1 + itr1 - 1];
		}
	}
	double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
		int size1 = nums1.size();
		int size2 = nums2.size();
		bool is_odd = (size1 + size2) % 2 == 1;
		double result = 0;
		if (is_odd) {
			result = findKth(nums1, nums2, 0, size1, 0, size2, (size1 + size2) / 2 + 1);
			return result;
		}
		else {
			result += findKth(nums1, nums2, 0, size1, 0, size2, (size1 + size2) / 2);
			result += findKth(nums1, nums2, 0, size1, 0, size2, (size1 + size2) / 2 + 1);
			result /= 2;
			return result;
		}
	}
};
收获就是可以将问题一般化,这样可以增加新的递归方式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值