递归
int find_kth(vector<int>& nums1, int begin1, int size1, vector<int>& nums2, int begin2, int size2, int k) { size1 = min(k, size1);//第k大最多只要前k个 size2 = min(k, size2); if (k == 1) { return min(nums1[begin1], nums2[begin2]); } if (size1 == 1) { if (begin2 + k - 1 < nums2.size()) return min(max(nums1[begin1], nums2[begin2 + k - 2]), nums2[begin2 + k - 1]); else return max(nums1[begin1], nums2[begin2 + k - 2]); } if (size2 == 1) { if (begin1 + k - 1 < nums1.size()) return min(max(nums2[begin2], nums1[begin1 + k - 2]), nums1[begin1 + k - 1]); else return max(nums2[begin1], nums1[begin1 + k - 2]); } double s = k / static_cast<double>(size1 + size2);//对应的比例位置 int q = s*(size1)+begin1;/**/ int p = s*(size2)+begin2;/**/ if (static_cast<int>(s*(size1)) + static_cast<int>(s*(size2))> k - 1 && (q - begin1) && (p - begin2)) //调节使 k刚好落在p 或 k,p k有可能是第k大在下一轮仍保留 { --p; --q; } if (static_cast<int>(s*(size1)) + static_cast<int>(s*(size2))< k - 3 && (q - begin1) && (p - begin2)) //调节使 k刚好落在p 或 k { ++p; ++q; } if (nums1[q] > nums2[p]) { k = k - (p - begin2); size1 = q - begin1 + 1; size2 -= (p - begin2); begin2 = p; } else { if (nums1[q] < nums2[p]) { k = k - (q - begin1); size1 -= (q - begin1); begin1 = q; size2 = p - begin2 + 1; } else { return nums1[q]; } } return find_kth(nums1, begin1, size1, nums2, begin2, size2, k); }
迭代
int find_kth(vector<int>& nums1, int begin1, int size1, vector<int>& nums2, int begin2, int size2, int k) { while (!(size2 == 1 || size1 == 1 || k == 1)) { size1 = min(k, size1);//第k大最多只要前k个 size2 = min(k, size2); double s = k / static_cast<double>(size1 + size2);//对应的比例位置 int q = s*(size1)+begin1;/**/ int p = s*(size2)+begin2;/**/ if (static_cast<int>(s*(size1)) + static_cast<int>(s*(size2)) > k - 1 && (q - begin1) && (p - begin2)) //调节使 k刚好落在p 或 k { --p; --q; } if (static_cast<int>(s*(size1)) + static_cast<int>(s*(size2)) < k - 3 && (q - begin1) && (p - begin2)) //调节使 k刚好落在p 或 k p k可能为第k大下轮保留 { ++p; ++q; } if (nums1[q] > nums2[p]) { k = k - (p - begin2); size1 = q - begin1 + 1; size2 -= (p - begin2); begin2 = p; } else { if (nums1[q] < nums2[p]) { k = k - (q - begin1); size1 -= (q - begin1); begin1 = q; size2 = p - begin2 + 1; } else { return nums1[q]; } } } if (k == 1) { return min(nums1[begin1], nums2[begin2]); } if (size1 == 1) { if (begin2 + k - 1 < nums2.size()) return min(max(nums1[begin1], nums2[begin2 + k - 2]), nums2[begin2 + k - 1]); else return max(nums1[begin1], nums2[begin2 + k - 2]); } if (size2 == 1) { if (begin1 + k - 1 < nums1.size()) return min(max(nums2[begin2], nums1[begin1 + k - 2]), nums1[begin1 + k - 1]); else return max(nums2[begin1], nums1[begin1 + k - 2]); } }