思路:设现在可用区间在nums1是[s1,t1),nums2:[s2,t2)
1.当一个数组可用区间为0的时候,由于另一个数组是已经排过序的,所以直接可得
当要取的是最小值或最大值时,也直接可得
2.明显两个数组总长度为偶数的时候需要取最中间两个元素/2.0,长度为奇数时,只需要求最中间那个.所以只需要分别求出最多两个元素,这一步没有想到可以抛弃中位数,直接转化为求第k大的数,导致第一版代码非常难看.
3.当需要取第k个数的时候,设nums1[tmp1],nums2[tmp2]分别是从各自起点出发的第k/2个数,那么假设nums1[tmp1]<nums2[tmp2],则明显[s1,tmp1]这个区间的都在第k个数之前,(因为[s1,tmp1],[s2,tmp2]都是各自区间最小的那一部分数,因为max(nums1[s1,tmp1])<min(nums1[tmp1+1,t1),nums2[tmp2,t2))),所以可以直接把它们去掉,别忘了k里面也要划去这个值
class Solution { public: const int inf = ~0u >> 1; vector<int> nums1,nums2; double findKthElement(int s1,int t1,int s2,int t2,int k) { // assert(t1 - s1 + t2 - s2 >= k); if(s1 == t1)return nums2[s2 + k - 1]; else if(s2 == t2)return nums1[s1 + k - 1]; if(k == 1)return min(nums1[s1],nums2[s2]); if(k == t1 - s1 + t2 - s2)return max(nums1[t1 - 1],nums2[t2 - 1]); int tmp1 = min(s1 + k/2 - 1,t1 - 1); int tmp2 = min(s2 + k/2 - 1,t2 - 1); if(nums1[tmp1] < nums2[tmp2]) { return findKthElement(tmp1 + 1,t1,s2,t2,k - tmp1 + s1 - 1); } else if(nums1[tmp1] > nums2[tmp2]) { return findKthElement(s1,t1,tmp2 + 1,t2,k - tmp2 + s2 - 1); } else { if((k & 1) == 0)return nums2[tmp2]; else return min((tmp1 + 1< t1?nums1[tmp1 + 1]:inf), (tmp2 + 1< t2?nums2[tmp2 + 1]:inf)); } } double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { this->nums1 = nums1; this->nums2 = nums2; sort(nums1.begin(),nums1.end()); sort(nums2.begin(),nums2.end()); int t1 = nums1.size(),t2 = nums2.size(); return ((t1 + t2) & 1) == 0? (findKthElement(0,t1,0,t2,(t1 + t2)/2) + findKthElement(0,t1,0,t2,(t1 + t2)/2 + 1))/2.0 :findKthElement(0,t1,0,t2,(t1 + t2)/2 + 1); } };
时间: 2024-10-18 00:52:13