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

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

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

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


总结

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


原创内容 转载请注明出处

分享给朋友:

相关文章

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

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

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

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

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

洛谷1656题解:基于Tarjan算法求解割边问题(附代码与详细步骤)

洛谷1656题解:基于Tarjan算法求解割边问题(附代码与详细步骤)

一、题目解读洛谷1656题要求在无向图中找出所有割边(即删除后导致图不连通的边)。题目核心在于判断图的连通性,并识别哪些边是“桥”。需理解图论中的连通分量概念,以及如何通过算法高效定位割边。二、解题思...

【牛客157题】:反转链表指定区间(虚拟头节点解法)

【牛客157题】:反转链表指定区间(虚拟头节点解法)

一、题目解读牛客第157题要求反转链表中第m到n个节点(包含m和n)的区间,并保持其他节点顺序不变。例如,给定链表1→2→3→4→5,m=2,n=4,应返回1→4→3→2→5。题目重点在于处理边界条件...

洛谷P1121题解:动态规划求解环形数组最大子段和问题(附代码注释)

洛谷P1121题解:动态规划求解环形数组最大子段和问题(附代码注释)

一、题目解读洛谷P1121题要求求解环形数组的最大子段和,即在一个环形数组中找到一个连续子段,使其元素和最大。环形数组的特殊性在于首尾元素可相连,需考虑线性子段与跨越首尾的环形子段两种情况。二、解题思...

牛客232639题解析:双指针+排序算法高效求解三角形数量(附代码详解)

牛客232639题解析:双指针+排序算法高效求解三角形数量(附代码详解)

一、题目解读牛客232639题要求计算一个整数数组中能够组成有效三角形的三边组合数量。根据三角形不等式,三边需满足任意两边之和大于第三边。例如,数组[3, 4, 5, 6]可组成两个有效三角形([3,...

发表评论

访客

看不清,换一张

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