力扣题目——1. 两数之和

注:本文的实现思路主要是基于JS(JavaScript),涉及到的一些函数都是JS中的自带函数

题目描述

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案


输入示例

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
输入:nums = [3,2,4], target = 6
输出:[1,2]
输入:nums = [3,3], target = 6
输出:[0,1]

解题思路

针对这种问题,本文提出了三种解决方案

  1. 暴力破解法,实践证明这个方法也是能通过所有测试用例的。思路是对于数组中的任一元素x,查找能否找到target - x,若找到,则返回下标。两层for循环即可简单解决问题。显然,时间复杂度为 O ( n 2 ) O(n^2) O(n2)
var twoSum = function(nums, target) {
    for (var i = 0; i < nums.length; i++) {
	    for (var j = i + 1; j < nums.length; j++) {
        	if(nums[i] + nums[j] === target)
            	return [i, j]
        }
    }
};
  1. 先对数组进行排序,然后使用两个指针同时从升序排序后数组的两端向中间移动,直到找到满足两个指针所指元素之和为target。由于使用了系统默认的排序算法,其时间复杂度为 O ( N l o g N ) O(NlogN) O(NlogN)。需要说明的是,由于排序后会导致元素的下标发生变化,所以需要使用一个变量记录原始数组,然后再使用一个循环遍历出该数值对应原始数组的下标。下面的代码看似很乱,其实思路很简单。
var twoSum = function(nums, target) {
	// 此处不能 temp = nums,否则nums变化会导致temp的变化
    const temp = [...nums]
    // 升序排序
    nums.sort((a,b)=> a-b)
    // 定义左右两个指针
    let left = 0, right = nums.length-1
    while(left !== right){
        //两个元素相加小于 target,说明 left太小,需要增加
        if (nums[left] + nums[right] < target) left ++
        //两个元素相加大于 target,说明 right太大,需要减小
        else if (nums[left] + nums[right] > target) right --
        else break
    }
    // 两个变量记录左右指针是否在原数组中找到了下标
    let l_flag = false, r_flag = false
    for (var i = 0; i < temp.length; i++) {
        if (l_flag && r_flag) break
        if (nums[left] === temp[i] && !l_flag) {left = i; l_flag = true}
        else if(nums[right] === temp[i] && !r_flag) {right = i; r_flag = true}
    }
    return [left, right]
};
  1. 使用哈希存储的方式,与其说是哈希存储,不如说是使用对象存储,其key是数组的元素值,value是数组的元素下标。这种方法的时间复杂度和空间复杂度都是 O ( N ) O(N) O(N)

值得注意的是,一定要先判断target - nums[i]是否已经在对象的属性中,若不存在,再向对象中添加对应的key和value。其原因也很简单,对象中的属性具有唯一性,要是直接把nums中的所有元素都添加对象中,再进行判断,重复的元素就回被覆盖。举个反例,nums = [1,1], target=2

var twoSum = function(nums, target) {
    let obj = {}
    for (var i = 0; i < nums.length; i++) {
        if (target - nums[i] in obj) 
        	return[i, obj[target - nums[i]]]
        obj[nums[i]] = i
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值