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

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

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

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


总结

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


原创内容 转载请注明出处

分享给朋友:

相关文章

力扣LCR182:字符串操作三连 从基础拼接到底层指针优化

力扣LCR182:字符串操作三连 从基础拼接到底层指针优化

题目重解需要将密码字符串从第target个字符开始进行重新排列,形成新的动态密码。例如输入"password"和target=3,结果应为"swordpas"。...

力扣第654题:最大二叉树解题教程 用数组构造最大二叉树

力扣第654题:最大二叉树解题教程 用数组构造最大二叉树

题目解读给定一个不含重复元素的整数数组,我们需要构建一棵最大二叉树。构建规则是:数组中的最大值作为根节点,其左侧子数组构建左子树,右侧子数组构建右子树,然后递归地应用这个规则。这种构建方式体现了分治思...

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

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

【力扣3115题解】数组中质数最大差值的求解(C++代码详解)

【力扣3115题解】数组中质数最大差值的求解(C++代码详解)

一、题目解读力扣3115题要求在一个整数数组中,找出两个质数之间的最大差值。若数组不存在质数,则返回0。题目核心在于高效筛选质数,并计算其索引差值的最大值,需兼顾时间与空间复杂度。二、解题思路参考代码...

标题:洛谷B3617题解析:八进制转十六进制算法实现与优化(附AC100代码)

标题:洛谷B3617题解析:八进制转十六进制算法实现与优化(附AC100代码)

一、题目解读洛谷B3617题要求将输入的八进制字符串转换为十六进制表示。题目需处理大数场景,且对输入合法性有明确限制(长度不超过1000,仅包含0-7字符)。由于八进制与十六进制无法直接转换,需借助十...

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

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

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

发表评论

访客

看不清,换一张

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