当算法遇上双指针:合并有序数组,轻松解决面试难题!

算法是面试中的一个难点,今天给大家带来一道经典的面试算法题,话不多说,直接上题目:

合并两个有序数组

给你两个按 非递减顺序 排列的整数数组 nums1nums2,另有两个整数 mn ,分别表示 nums1nums2 中的元素数目。 请你 合并 nums2nums1 中,使合并后的数组同样按 非递减顺序 排列。

注意: 最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n

这道题不是很难,我们很容易就会想到,题目说要合并两个有序数组,合并后的数组同样是有序的。那咱就先合并咯:

js 复制代码
nums1.splice(m,n,...nums2)

利用数组中的splice方法,我们很容易的就将两个数组合并了。接下来怎么办呢?数组都合并好了,那么接下来就是排序了,排序的方法有很多,咱这就直接简单粗暴的用sort方法了。

js 复制代码
nums1.sort((a,b) => a-b)

那做到这,咱就完成了对吧

js 复制代码
var merge = function(nums1, m, nums2, n) {
    nums1.splice(m,n,...nums2)
    nums1.sort((a,b) => a-b)
    return nums1
};

sort() 方法通常使用快速排序或归并排序算法,其平均时间复杂度为 O(n log n),其中n为数组的长度,所以这里的时间复杂度是 O((m+n) log (m+n))。效率好像不是很好,那么这个时候面试官就会问,有什么效率更高的方法吗,或者怎么优化一下性能。

那必须有,我们可以这么干

  1. 初始化两个指针 p1p2 分别指向 nums1 和 nums2 的末尾有效元素的位置(即初始分别为 m-1 和 n-1)。
  2. 初始化一个指针 p 指向 nums1 的末尾,作为合并后数组的插入位置。
  3. 从后往前遍历 nums1 和 nums2,比较 nums1[p1] 和 nums2[p2] 的大小,将较大的元素放入 nums1 的末尾(即位置 p 处),并移动对应指针。
  4. 如果 nums2 中还有元素未处理完,直接将剩余的元素插入到 nums1 的前面。

以下是具体的 JavaScript 实现代码:

js 复制代码
var merge = function(nums1, m, nums2, n) {
    let p1 = m - 1;
    let p2 = n - 1;
    let p = m + n - 1;

    while (p1 >= 0 && p2 >= 0) {
        if (nums1[p1] > nums2[p2]) {
            nums1[p] = nums1[p1];
            p1--;
        } else {
            nums1[p] = nums2[p2];
            p2--;
        }
        p--;
    }

    // 将 nums2 中剩余的元素复制到 nums1 的前面
    while (p2 >= 0) {
        nums1[p] = nums2[p2];
        p2--;
        p--;
    }
};

这种双指针的方法避免了一些重复的排序操作,时间复杂度为O(m+n)。

假如您也和我一样,在准备春招。欢迎加我微信shunwuyu,这里有几十位一心去大厂的友友可以相互鼓励,分享信息,模拟面试,共读源码,齐刷算法,手撕面经。来吧,友友们!

相关推荐
独好紫罗兰11 分钟前
洛谷题单3-P1720 月落乌啼算钱(斐波那契数列)-python-流程图重构
开发语言·算法·leetcode
啥都鼓捣的小yao1 小时前
Python解决“数字插入”问题
python·算法
qystca2 小时前
蓝桥云客--回文数组
算法
每次的天空2 小时前
Android学习总结之算法篇五(字符串)
android·学习·算法
Fantasydg3 小时前
DAY 37 leetcode 454--哈希表.四数相加
算法·leetcode·散列表
Dontla3 小时前
前端页面鼠标移动监控(鼠标运动、鼠标监控)鼠标节流处理、throttle、限制触发频率(setTimeout、clearInterval)
前端·javascript
前端 贾公子3 小时前
LeetCode 2442:统计反转后的不同整数数量
算法·leetcode·职场和发展
再学一点就睡3 小时前
深拷贝与浅拷贝:代码世界里的永恒与瞬间
前端·javascript
lmy201211083 小时前
GESP:2025-3月等级8-T1-上学
c++·算法·图论·dijkstra
CrimsonHu3 小时前
B站首页的 Banner 这么好看,我用原生 JS + 三大框架统统给你复刻一遍!
前端·javascript·css