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

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

合并两个有序数组

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

相关推荐
程序新视界3 分钟前
在职场,尽量不要成为这样的“人才”
面试·求职
华仔啊12 分钟前
面试都被问懵了?CSS 的 flex:1 和 flex:auto 真不是一回事!90%的人都搞错了
前端·javascript
前端康师傅14 分钟前
JavaScript 函数详解
前端·javascript
小奋斗15 分钟前
以Chrome 为代表的浏览器架构详解
面试·程序员
songx_9917 分钟前
leetcode10(跳跃游戏 II)
数据结构·算法·leetcode
葡萄城技术团队18 分钟前
从基础到实战:一文吃透 JS Tuples 与 Records 的所有核心用法
javascript
在未来等你25 分钟前
Elasticsearch面试精讲 Day 12:数据建模与字段类型选择
大数据·分布式·elasticsearch·搜索引擎·面试
a587691 小时前
消息队列(MQ)初级入门:详解RabbitMQ与Kafka
java·分布式·microsoft·面试·kafka·rabbitmq
@小红花1 小时前
从0到1学习Vue框架Day03
前端·javascript·vue.js·学习·ecmascript
前端与小赵1 小时前
vue3中 ref() 和 reactive() 的区别
前端·javascript·vue.js