标签:pop erase 通过 for open 提前 array private oss
这道题要求两个有序数组,找出中间位置的平均值;
解题思路:
1、取A数组的中间位置mid的值key,去B数组中查找最靠近key且小于等于key的位置index;
2、将原数组切成三段,index和mid之前数组的为新的left数组;right1跟right2为新的right数组;mid到right1和index到right2为新的middle数组;
3、通过判断数组的长度,知道在哪个数组段;当运气好找到中间位置的时候,则可提前给出结果;
4、将切割完的数组,数组长度比较长的作为A数组,比较短的作为B数组继续执行1操作;
5、当数组长度小于等于4的时候结束;直接排序给结果;
这里用到了滚动数组的思想,让4更容易操作;
class Solution { private: int FirstLower(const int* nums, int left, int right, int key) { int mid = left; while (left < right) { if (left + 1 == right) { if (nums[left] > key) return -1; return left; } mid = (left + right) >> 1; if (nums[mid] > key) right = mid; else left = mid; } return -1; } public: double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { int* nums[2]; nums[0] = nums1.data(); nums[1] = nums2.data(); int row = 0; int left[2] = {0, 0}; int right[2] = {(int)nums1.size(), (int)nums2.size()}; int right_static[2] = {(int)nums1.size(), (int)nums2.size()}; int total_static = right[0] + right[1]; for (int i = 0; i < 2; ++i) { if (right[i] == 0) { if (1 == right[1-i] % 2) return nums[1-i][right[1-i]/2]; return (nums[1-i][right[1-i]/2] + nums[1-i][right[1-i]/2-1]) / 2.0; } } int need = 0; int c0 = 0, c1 = 0; while (true) { c0 = 0; c1 = 0; if (left[row] < right_static[row]) c0 = right[row] - left[row]; if (left[1-row] < right_static[1-row]) c1 = right[1-row] - left[1-row]; if (c0 + c1 <= 4) break; if (c0 <= c1) { row = 1-row; } int mid = (right[row] + left[row]) >> 1; int index1_row = FirstLower(nums[1-row], left[1-row], right[1-row], nums[row][mid]); if (index1_row >= 0) ++index1_row; int may_left = mid + left[1-row]; int may_right = total_static - right[row] - right[1-row]; int may_middle = right[row] - mid + right[1-row] - left[1-row]; if (index1_row >= 0) { may_left += index1_row - left[1-row]; may_middle -= index1_row - left[1-row]; } if (may_left > may_right) { if (may_left - may_right > may_middle) { right[row] = mid; if (index1_row == -1) right[1-row] = left[1-row]; else right[1-row] = index1_row; } else if (may_left - may_right < may_middle) { left[row] = mid; if (index1_row >= 0) left[1-row] = index1_row; } else { if (left[1-row] < right[1-row]) { if (index1_row == -1) { right[1-row] = left[1-row] + 1; } else { left[1-row] = index1_row - 1; if (index1_row + 1 <= right[1-row]) right[1-row] = index1_row+1; } } else { left[1-row] = right[1-row]; } right[row] = mid + 1; if (left[row] < mid) left[row] = mid - 1; else left[row] = mid; } } else { if (may_right - may_left < may_middle) { left[row] = mid; if (index1_row >= 0) left[1-row] = index1_row; } else { std::cout << "impossible\n"; } } need = total_static - right[row] - right[1-row] - left[row] - left[1-row]; } vector<int> result; for (int i = 0; i < 2; ++i) { for (int j = left[i]; j < right[i]; ++j) { if (0 <= j && j < right_static[i]) result.push_back(nums[i][j]); } } sort(result.begin(), result.end()); while (need > 0) { result.erase(result.begin()); --need; } while (need < 0) { result.pop_back(); ++need; } if (result.size() % 2 == 0) { if (result.size() == 2) return (result[0] + result[1]) / 2.0; else if (result.size() == 4) return (result[1] + result[2] ) / 2.0; } else { if (result.size() == 1) return result[0]/ 1.0; else if (result.size() == 3) return result[1] / 1.0; } return 0.0; } };
代码中的输出impossilbe的那个判断条件,是因为当右边的数组r大于左边l加中间m的时候,则上一轮的切割结果一定比当前的切割结果差距更大;那么目标位置应当到右边去查找;则与此轮的查找位置相矛盾;
leetcode 4 Median of Two Sorted Arrays
标签:pop erase 通过 for open 提前 array private oss
原文地址:https://www.cnblogs.com/czwlinux/p/12298378.html