两数之和(暴力遍历,哈希表,双指针)

199 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

题目描述

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

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

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

示例 1:

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

输入:nums = [3,2,4], target = 6 输出:[1,2] 示例 3:

输入:nums = [3,3], target = 6 输出:[0,1]

提示:

2 <= nums.length <= 103 -109 <= nums[i] <= 109 -109 <= target <= 109 只会存在一个有效答案

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/tw… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

暴力遍历

当看到这道题时,首先想到的是暴力遍历

a = input().split()
target = int(input())

nums = []
l = []

for i in range(len(a)):
    nums.append(int(a[i]))

for i in range(len(nums)):
    for each in range(i + 1, len(nums)):
        if nums[i] + nums[each] == target:
            l.append(i)
            l.append(each)
            
print(l)

但这样的结果比较慢,在力扣上耗时472ms

哈希表

其实关于查找我们可以选择哈希算法。 即:用字典存储元素的值和位置

n = input().split()
nums = []
for i in n:
    nums.append(int(i))

target = int(input())

def twoSum(nums, target):
    # dic 记录元素和元素所对应的位置
    dic = {value: index for index, value in enumerate (nums)}

    for i in range(len(nums)):
        d = target - nums[i]
        if d in dic and i != dic[d]: # 判断值是否存在并且返回位置
            return [i, dic[d]]

print(twoSum(nums, target))

我们也可以用列表模拟哈希表,比如说判断 target - nums[i] 是否在列表中,并返回其所在的位置(注意:这个位置不能等于 i )

在这道题两种做法的耗时差不多,都是40ms左右,但数据大了,哈希表会快一些,因为判断 target - nums[i] 是否在列表中时间复杂度是 O(n) 其中 n 是列表的长度,而 判断 target - nums[i] 是否在哈希表中时间复杂度是 O(1)。

双指针

此外,还可以选择双指针。

n = input().split()
nums = []
for i in n:
    nums.append(int(i))

target = int(input())

def twoSum(nums, target):

    for start in range(len(nums)):
        end = len(nums) - 1
        while start < end:
            if nums[start] + nums[end] == target:
                return [start, end]
            else:
                end -= 1

print(twoSum(nums, target))

其实这道题双指针和两重循环,一个从头至尾循环一个从尾往前循环没有什么区别。一般来说双指针对有序的列表比较好用。这样的用时大概44ms左右。