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

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

9个月前 (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)))

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


总结

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


原创内容 转载请注明出处

分享给朋友:

相关文章

线性遍历+二进制 6行代码征服二进制链表转整数

线性遍历+二进制 6行代码征服二进制链表转整数

力扣1290.二进制链表转整数题目本质给定一个单链表的头节点head,链表中每个节点的值为0或1。链表表示一个‌最高有效位在前‌的二进制数字,要求将其转换为对应的十进制整数。例如链表1→0→1对应的二...

征服力扣704题:三步掌握经典二分查找算法

征服力扣704题:三步掌握经典二分查找算法

题目重解我们面对的是算法领域最经典的二分查找问题:在一个已排序的整数数组中,快速定位目标值的位置。就像在一本按字母顺序排列的字典中查找单词,我们不需要逐页翻阅,而是通过不断折半的方式快速缩小搜索范围,...

NOIP2005 普及组 洛谷P1408 背包问题的空间优化技巧与实战应用

NOIP2005 普及组 洛谷P1408 背包问题的空间优化技巧与实战应用

题目重解想象你是一名药师,有t分钟在山上采集m种草药。每种草药需要time分钟采集,价值为num。这就像考试时分配时间做题,要选择收益最大的题目组合。题目要求计算在规定时间内能获得的最大草药价值。解题...

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

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

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

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

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

发表评论

访客

看不清,换一张

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