力扣4. 寻找两个正序数组的中位数

 

题目:【https://leetcode.cn/problems/median-of-two-sorted-arrays/?envType=study-plan-v2&envId=top-interview-150

一道困难题,常规思路不难,但是真的难写,边界要仔细思考。

下面是我第一轮的思路,虽然非常常规,但是时间复杂度并不高,注意要把奇数偶数分开写,一个是降低了时间复杂度,另一个是好写。。。不然会出现一堆判断或者三目表达式。

 1 class Solution {
 2 public:
 3     double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
 4         int n1 = nums1.size(), n2 = nums2.size();
 5         int n = n1 + n2;
 6         int num = INT_MIN;
 7         int i = 0, i1 = 0, i2 = 0;
 8         int hn = n / 2;
 9         if (n & 1) {
10             for (; ; ++i) {
11                 if (i1 < n1 && i2 < n2) {
12                     if (i == hn) return 1.0 * min(nums1[i1], nums2[i2]);
13                     if (nums1[i1] > nums2[i2]) i2++; else i1++;
14                 } else if (i1 >= n1) {
15                     return nums2[hn - n1];
16                 } else if (i2 >= n2) {
17                     return nums1[hn - n2];
18                 }
19             }
20         } else {
21             for (; ; ++i) {
22                 if (i1 < n1 && i2 < n2) {
23                     if (i == hn - 1) num = min(nums1[i1], nums2[i2]);
24                     else if (i == hn) return (num + min(nums1[i1], nums2[i2])) / 2.0;
25 
26                     if (nums1[i1] > nums2[i2]) i2++; else i1++;
27                 } else if (i1 >= n1) {
28                     return INT_MIN == num ? (nums2[hn - n1 - 1] + nums2[hn - n1]) / 2.0 : (num + nums2[i2]) / 2.0;
29                 } else if (i2 >= n2) {
30                     return INT_MIN == num ? (nums1[hn - n2 - 1] + nums1[hn - n2]) / 2.0 : (num + nums1[i1]) / 2.0;
31                 }
32             }
33         }
34         return 0;
35     }
36 };

 

下面这个做法是参考官方题解,写了一遍,满足题目要求的O(log (m+n)时间复杂度,不过实际试了一下,大量测试用例中,元素较少的情况下,时间复杂度反倒变高了。

这种做法最终要的几个点如下

① 要按照第k大的数来找,不要一门心思的找中数,容易陷入奇数偶数的大量判断中。

② 代码量不大,想理解并且快速手搓一遍不容易,理解思路+边界判断。

 1 class Solution {
 2 public:
 3     int findk(vector<int>& nums1, vector<int>& nums2, int k)
 4     {
 5         int n1 = nums1.size(), n2 = nums2.size();
 6         int i1 = 0, i2 = 0;
 7         for (;;) {
 8             if (i1 == n1) return nums2[i2 + k - 1];
 9             if (i2 == n2) return nums1[i1 + k - 1];
10             if (1 == k) return min(nums1[i1], nums2[i2]);
11             int hk = k / 2;
12             int ti1 = min(i1 + hk, n1) - 1;
13             int ti2 = min(i2 + hk, n2) - 1;
14             // printf("In, k = %d, hk = %d, i1 = %d, i2 = %d, ti1 = %d, ti2 = %d, [ %s ]\n", 
15             //         k, hk, i1, i2, ti1, ti2, nums1[ti1] > nums2[ti2] ? "if" : "else");
16             if (nums1[ti1] > nums2[ti2]) {
17                 k -= min(hk, n2 - i2);
18                 i2 = ti2 + 1;
19             } else {
20                 k -= min(hk, n1 - i1);
21                 i1 = ti1 + 1;
22             }
23             // printf("Out, k = %d, i1 = %d, i2 = %d\n", k, i1, i2);
24         }
25     }
26 
27     double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
28         int n1 = nums1.size(), n2 = nums2.size();
29         int n = n1 + n2;
30         if (n & 1)
31             return findk(nums1, nums2, (n + 1) / 2);
32         else
33             return (findk(nums1, nums2, n / 2) + findk(nums1, nums2, n / 2 + 1)) / 2.0;
34     }
35 };

 

posted @ 2025-06-05 14:39  J&YANG  阅读(10)  评论(0)    收藏  举报