当前位置:首页 > 力扣 > 力扣第44题:寻找两个正序数组的中位数 - 合并排序解法详解

力扣第44题:寻找两个正序数组的中位数 - 合并排序解法详解

3个月前 (06-15)

力扣第44题:寻找两个正序数组的中位数 - 合并排序解法详解 C++ 数组 合并排序 双指针 算法 力扣 第1张


内容简介

本文详细解析了力扣第44题"寻找两个正序数组的中位数"的合并排序解法。通过双指针技术合并两个有序数组,然后直接计算合并后数组的中位数。虽然时间复杂度为O(m+n),但这种方法思路清晰,代码简洁,是理解该问题的基础解法。文章包含完整注释代码、算法思路讲解和复杂度分析。


算法思路

‌1.合并两个有序数组‌:使用双指针(min1和min2)分别遍历nums1和nums2

2‌.比较元素大小‌:每次取两个指针所指元素的较小值放入合并数组

‌3.处理剩余元素‌:当某个数组遍历完后,直接将另一个数组剩余元素加入

‌4.计算中位数‌:根据合并后数组长度的奇偶性返回相应中位数值


完整代码(带注释)

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        vector<int> nums;  // 存储合并后的有序数组
        int min1 = 0;      // nums1的遍历指针
        int min2 = 0;      // nums2的遍历指针
        
        // 合并两个有序数组
        while(min1 != nums1.size() || min2 != nums2.size()) {
            // 处理nums2已遍历完的情况
            if(min2 == nums2.size()) {
                nums.push_back(nums1[min1]);
                min1++;
            }
            // 处理nums1已遍历完的情况
            else if(min1 == nums1.size()) {
                nums.push_back(nums2[min2]);
                min2++;
            }
            // 两个数组都还有元素时比较大小
            else {
                // 取当前两个指针位置的较小值
                int n = nums1[min1] < nums2[min2] ? nums1[min1] : nums2[min2];
                nums.push_back(n);
                // 移动较小值所在数组的指针
                n == nums1[min1] ? min1++ : min2++;
            }
        }

        // 计算合并后数组的中位数
        if(nums.size() % 2) {  // 数组长度为奇数
            return nums[nums.size()/2];
        }
        else {  // 数组长度为偶数
            int tmp1 = nums[nums.size()/2];      // 中间右侧元素
            int tmp2 = nums[nums.size()/2-1];    // 中间左侧元素
            return (tmp1 + tmp2) / 2.0;          // 返回平均值
        }
    }
};


复杂度分析

‌时间复杂度‌:O(m+n),需要完整遍历两个输入数组的所有元素

‌空间复杂度‌:O(m+n),需要额外空间存储合并后的数组


优化方向

虽然这种解法易于理解,但可以通过以下方法进一步优化:

二分查找法‌:将时间复杂度优化到O(log(min(m,n)))

‌不实际合并数组‌:通过虚拟索引直接找到中位数位置,节省空间


总结

本文提供的合并排序解法是解决两个有序数组中位数问题的基础方法,代码简洁明了,适合作为学习该问题的入门方案。理解这种解法后,可以进一步探索更高效的二分查找解法。


原创内容 转载请注明出处

分享给朋友:

相关文章

力扣451:ASCII数组计数法 用128个桶解决频率排序问题

力扣451:ASCII数组计数法 用128个桶解决频率排序问题

题目重解给定一个字符串,将字符按照出现频率降序排列。例如输入"tree",可能返回"eetr"或"eert"。题目要求我们不考虑字母顺序,只...

力扣第1991题:寻找数组的中心索引 如何找到左右和相等的中心索引

力扣第1991题:寻找数组的中心索引 如何找到左右和相等的中心索引

题目解读给定一个整数数组,我们需要找到一个中心索引,使得该索引左侧所有元素的和等于右侧所有元素的和。如果不存在这样的索引,则返回-1。中心索引的定义不包含在左右两侧的和计算中。这个问题考察对数组遍历和...

牛客DP41精讲:当背包必须装满时,你的状态转移方程该如何调整?

牛客DP41精讲:当背包必须装满时,你的状态转移方程该如何调整?

题目重解我们面对一个经典背包问题的变体:给定n个物品,每个物品有重量w和价值v,背包容量为V。需要回答两个问题:1) 普通情况下能获得的最大价值;2) 必须恰好装满背包时的最大价值(若无法装满则输出0...

手搓顺序表类代码注释与详解:从零实现动态数组(新手教程)

一、简介和特点顺序表(Sequential List)是数据结构中基础的一种线性表,其特点是将数据元素存储在连续的内存空间中。通过数组实现,支持随机访问(即通过索引直接访问元素),适用于频繁随机读取的...

牛客14496题解:括号最大深度问题(栈思想与代码优化)

牛客14496题解:括号最大深度问题(栈思想与代码优化)

一、题目解读牛客14496题要求计算给定括号字符串中的最大深度。例如,对于字符串 "(()())",最大深度为2。题目考察对括号嵌套结构的理解,以及如何通过编程找到最深嵌套层次。二...

力扣3112题解法:带时间限制的最短路径问题解析(C++代码)

力扣3112题解法:带时间限制的最短路径问题解析(C++代码)

一、题目解读力扣3112题要求解决带时间限制的最短路径问题:给定一个有向图,节点具有消失时间,需计算从起点到各节点的最短路径,且路径总时间不能超过节点的消失时间。题目难点在于需在传统最短路径算法(如D...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。