【剑指Offer】数组(一)双指针 - 排序数组中的两个数字之和 - JavaScript

263 阅读2分钟

嗨!~ 大家好,我是YK菌 🐷 ,一个微系前端 ✨,爱思考,爱总结,爱记录,爱分享 🏹,欢迎关注我呀 😘 ~ [微信公众号:YK菌]

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第 9 天,点击查看活动详情

今天继续来刷《剑指offer(专项突破版)》,原书是Java版本的,这里就是以JavaScript角度来看这些算法题。

剑指 Offer II 006. 排序数组中两个数字之和

给定一个已按照升序排列的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target
函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 0 开始计数 ,所以答案数组应当满足 0 <= answer[0] < answer[1] < numbers.length 。
假设数组中存在且只存在一对符合条件的数字,同时一个数字不能使用两次。

分析

这题和主站的第一题【LeetCode】力扣启蒙题——两数之和 & 两数之和II(简单) - 掘金 (juejin.cn)类似。只是需要注意下下标问题。

  1. 暴力解法直接遍历所有两数之和,找到满足条件的解,时间复杂度为O(n2)O(n^2),空间复杂度为O(1)O(1)
  2. 由于数组是排序的,所以可以使用二分查找进行搜索,所以暴力解法优化后时间复杂度为O(nlogn)O(nlogn),空间复杂度为O(1)O(1)
  3. 还可以使用空间换时间的方法,设计一个map用来存储遍历过的值,时间复杂度为O(1)O(1),空间复杂度为O(n)O(n)
  4. 数组是升序排列的,所以我们可以考虑使用双指针,一种从两头往中间缩小的对撞指针。时间复杂度为O(n)O(n),空间复杂度为O(1)O(1)
    • 如果两数之和大于target,需要缩小最大值,也就是需要左移右指针
    • 如果两数之和小于target,需要扩大最小值,也就是需要右移左指针

题解

/**
 * @param {number[]} numbers
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function(numbers, target) {
    // 定义头尾指针
    let i = 0
    let j = numbers.length - 1
    while(i < j){
        let sum = numbers[i] + numbers[j]
        if(sum === target){
            return [i, j];
        }else if (sum < target) {
            i++;
        }else{
            j--;
        }
    }
};

image.png

最后,欢迎关注我的专栏,和YK菌做好朋友