跳转至

1. 两数之和#

问题描述#

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

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

 

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

解题思路#

常规做法遍历所有情况直到满足条件。

1
2
3
4
5
6
7
8
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        n = len(nums)
        for i in range(n):
            for j in range(i + 1, n):
                if nums[i] + nums[j] == target:
                    return [i, j]
        return []

s1.png

然后就超时了,这说明 \(\mathcal{O}(n^2)\) 的复杂度过不了。


一种解决方法是,我们先对数据进行排序,同时要保留数据原始的下标,然后使用类似二分法的过程来求解。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        p = [(i, x) for i, x in enumerate(nums)]
        p.sort(key=lambda x: x[1])

        lo, hi = 0, len(nums) - 1
        while lo < hi:
            t = p[lo][1] + p[hi][1]
            if t == target:
                # return sorted([p[lo][0], p[hi][0]])
                return [p[lo][0], p[hi][0]] # 答案与下标顺序无关
            elif t < target:
                lo += 1
            else:
                hi -= 1

        return []

s2.png


另一种方法就是使用一个字典来保留已经遇到的数字及其下标。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        m = {}
        for i, x in enumerate(nums):
            res = target - x
            if res in m:
                return [m[res], i]
            m[x] = i

        return []

s3.png

返回顶部

在手机上阅读