【LeetCode】力扣启蒙题——两数之和 & 两数之和II(简单)

858 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

相信很多人的力扣启蒙题就是——力扣第一题:两数之和,今天我们来学习这道题的解法

在解这道题之前,我看了下我在力扣中,这道题的刷题记录

image.png

从下往上,大概就能看出来我学习编程,以及那段时间使用的编程语言的一些变化,从C到Python到Java,最后固定到JavaScript了~~ 哈哈

1. 两数之和(简单)

leetcode-cn.com/problems/tw…

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回答案。

【解法一】两层循环 - 暴力查找

拿到题最容易想到的就是两层循环遍历,固定一个元素,查找另一个元素 在这里插入图片描述

i遍历一遍数组; ji+1开始遍历剩余部分,看是否能找到等于 target-nums[i] 的元素, 找到返回下标

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function (nums, target) {
  for (let i = 0; i < nums.length - 1; i++) {
    for (let j = i + 1; j < nums.length; j++) {
      if (nums[j] === target - nums[i]) {
        return [i, j];
      }
    }
  }
  return [];
};

在这里插入图片描述

【解法二】一层循环 - Map

复习一下ES6的Map

【技巧】map

map会维护插入时的顺序

// 定义空map
let map = new Map();
// 添加元素
map.set("key1","value1").set("key2", "value2");
// 查询元素
map.has("key1"); // true
map.get("key1"); // "value1"
map.size === 2;

构建映射【值:下标】

遍历nums构建map,之后只需在map中查找元素,而不需要每次都遍历剩余数组了

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function(nums, target) {
    let map = new Map();
    for(let i = 0; i < nums.length; i++){
	    let value = target - nums[i]
	    if(map.has(value)){
	        return [map.get(value), i]
	    }else {
	    	// 找不到就插入到 map中
	        map.set(nums[i], i)
	    }
    }
    return [];
};

在这里插入图片描述

【坑】注意题目条件 不可以取两次自己的下标

注意这里有一个坑,往map中存数据(set)操作要在判断语句之后! 因为不可以重复取两次自己,所以要在之前存入的元素中查找!!!

167. 两数之和 II - 输入有序数组(简单)

leetcode-cn.com/problems/tw…

给定一个已按照 升序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。

不考虑有序数组。就当第1题做

【解法一】两层循环-暴力查找

/**
 * @param {number[]} numbers
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function(numbers, target) {
    for(let i = 0; i < numbers.length; i++){
        for(let j = i+1; j < numbers.length; j++){
            if(numbers[j] === target - numbers[i]){
                return [i + 1, j + 1]
            }
        }
    }
};

在这里插入图片描述

考虑有序数组,可以优化

是有序数组,所以可以从两头往中间找

【解法二】头尾指针 - 对撞指针

/**
 * @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+1, j+1];
        }else if (sum < target) {
            i++;
        }else{
            j--;
        }
    }
};

在这里插入图片描述