力扣第4题 寻找两个正序数组的中位数 困难 合并暴力 求解c++ 有优化代码

题目

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

困难

        给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。

算法的时间复杂度应该为 O(log (m+n)) 。

示例 1:

输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2

示例 2:

输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5

提示:

  • nums1.length == m
  • nums2.length == n
  • 0 <= m <= 1000
  • 0 <= n <= 1000
  • 1 <= m + n <= 2000
  • -106 <= nums1[i], nums2[i] <= 106

思路和解题方法

  1. 首先,创建一个空的vector ans,用于存储合并后的有序数组。
  2. 初始化四个指针:n1和n2分别指向nums1和nums2的起始位置,a1和a2分别记录已经合并到ans中的元素个数。
  3. 对nums1和nums2进行排序,使它们分别按升序排列。
  4. 在一个循环中,比较nums1[n1]和nums2[n2]指向的元素:
    • 如果nums1[n1]大于等于nums2[n2],则将nums2[n2]加入ans中,同时将n2和a2递增1。
    • 否则,将nums1[n1]加入ans中,同时将n1和a1递增1。
    • 每一次比较操作都会向ans中添加一个元素。
  5. 循环结束后,判断是否还有剩余的元素未添加到ans中:
    • 如果a1小于nums1的长度,说明nums1还有剩余元素未添加到ans中,将剩余元素全部添加到ans中。
    • 如果a2小于nums2的长度,说明nums2还有剩余元素未添加到ans中,将剩余元素全部添加到ans中。
  6. 计算ans的长度n,并根据n的奇偶性来确定返回值:
    • 如果n是奇数,返回ans[n/2]作为中位数。
    • 如果n是偶数,返回(ans[n/2] + ans[(n+1)/2])/2.0作为中位数。

复杂度

        时间复杂度:

                O(m+n)

时间复杂度:在最坏情况下,该算法需要遍历两个输入数组 nums1nums2,直到其中一个数组的所有元素都被处理完。因此,时间复杂度为 O(m+n),其中 m 和 n 分别是 nums1nums2 的长度。

        空间复杂度

                O(m+n)

空间复杂度:这段代码使用了一个额外的数组 ans 来存储合并后的有序数组,其长度为 m+n。因此,空间复杂度为 O(m+n)。

优化前  c++ 代码(优化后代码在后面)

 
class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        vector<int> ans; // 用于存储合并后的有序数组
        int n1 = 0, n2 = 0; // 分别指向 nums1 和 nums2 当前比较的元素索引
        int a1 = 0, a2 = 0; // 记录已经合并到 ans 的元素个数

        while (n1 < nums1.size() && n2 < nums2.size()) { // 当两个数组都还有元素可以比较时
            if (nums1[n1] >= nums2[n2]) { // 如果 nums1 当前的元素大于等于 nums2 当前的元素
                ans.push_back(nums2[n2]); // 将 nums2 当前的元素添加到 ans 中
                n2++; // nums2 指针后移
                a2++; // 已合并到 ans 的元素个数加一
            }
            else { // 如果 nums1 当前的元素小于 nums2 当前的元素
                ans.push_back(nums1[n1]); // 将 nums1 当前的元素添加到 ans 中
                n1++; // nums1 指针后移
                a1++; // 已合并到 ans 的元素个数加一
            }
        }

        if (a1 < nums1.size()) { // 如果 nums1 还有剩余元素未添加到 ans 中
            for (a1; a1 < nums1.size(); a1++) {
                ans.push_back(nums1[a1]); // 将剩余的 nums1 元素添加到 ans 中
            }
        }
        else if (a2 < nums2.size()) { // 如果 nums2 还有剩余元素未添加到 ans 中
            for (a2; a2 < nums2.size(); a2++) {
                ans.push_back(nums2[a2]); // 将剩余的 nums2 元素添加到 ans 中
            }
        }

        int n = ans.size() - 1; // 合并后的有序数组的最后一个元素索引

        if (ans.size() % 2 == 1) { // 如果合并后的数组长度为奇数
            return ans[n / 2] / 1.0; // 返回中间元素作为中位数(由于除法运算,转换为浮点数)
        }
        else { // 如果合并后的数组长度为偶数
            return (ans[n / 2] + ans[(n + 1) / 2]) / 2.0; // 返回中间两个元素的平均值作为中位数
        }
    }
};

优化后c++代码

class Solution {
public:
    double findMedianSortedArrays(const vector<int>& nums1, const vector<int>& nums2) {
        vector<int> ans; // 用来存储合并后的有序数组
        int n1 = 0, n2 = 0; // 分别表示遍历 nums1 和 nums2 的指针

        // 合并两个有序数组,直到其中一个数组的所有元素都被处理完
        while (n1 < nums1.size() && n2 < nums2.size()) {
            // 比较当前指针位置的元素,将较小的元素添加到 ans 中,并将相应指针向后移动一位
            ans.push_back(nums1[n1] >= nums2[n2] ? nums2[n2++] : nums1[n1++]);
        }

        // 将剩余未处理的元素添加到 ans 中
        for (; n1 < nums1.size(); n1++) {
            ans.push_back(nums1[n1]);
        }

        for (; n2 < nums2.size(); n2++) {
            ans.push_back(nums2[n2]);
        }

        int n = ans.size() - 1;
        int medianIndex = n / 2; // 计算中位数的索引位置

        // 如果 ans 的长度为奇数,返回中间的元素;如果长度为偶数,返回中间两个元素的平均值
        return (ans[medianIndex] + ans[n - medianIndex]) / 2.0;
    }
};

觉得有用的话可以点点赞,支持一下。

如果愿意的话关注一下。会对你有更多的帮助。

每天都会不定时更新哦  >人<  。

posted @   lenyan~  阅读(13)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示