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

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

合并两个有序数组

给你两个按 非递减顺序 排列的整数数组 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,这里有几十位一心去大厂的友友可以相互鼓励,分享信息,模拟面试,共读源码,齐刷算法,手撕面经。来吧,友友们!

相关推荐
iceslime12 分钟前
旅行商问题(TSP)的 C++ 动态规划解法教学攻略
数据结构·c++·算法·算法设计与分析
spionbo17 分钟前
Vue 表情包输入组件实现代码及完整开发流程解析
前端·javascript·面试
全宝17 分钟前
✏️Canvas实现环形文字
前端·javascript·canvas
前端梭哈攻城狮30 分钟前
uniapp图片上传添加水印/压缩/剪裁
前端·javascript·vue.js
天涯学馆30 分钟前
前后端分离的 API 设计:技术深度剖析
前端·javascript·面试
爱编程的喵32 分钟前
深入理解JavaScript原型机制:从Java到JS的面向对象编程之路
java·前端·javascript
独立开阀者_FwtCoder32 分钟前
Cursor 1.0 重磅发来袭(毛骨悚然,开始学习你如何编码)
前端·javascript·github
五点六六六37 分钟前
一些关于TreeShaking的AST的理解
前端·javascript·前端工程化
aichitang20241 小时前
矩阵详解:从基础概念到实际应用
线性代数·算法·矩阵
异常君1 小时前
Spring 中的 FactoryBean 与 BeanFactory:核心概念深度解析
java·spring·面试