459. 查找和为指定数的数组数字 题解 | 豆包MarsCode AI刷题

95 阅读3分钟

459 查找和为指定数的数组数字

问题描述

小R有一个按升序排序的整数数组,他的任务是查找其中两数,使得它们的和等于给定的目标数字。如果存在多对符合条件的数字,输出找到的第一对数字。若无符合条件的组合,则返回结果异常。每次返回的结果包括是否找到结果的状态及该两数的索引和它们的值。

例如:在输入的数组 [1, 2, 4, 7, 11, 15] 中,找到的第一对和为 6 的数字是 2 和 4

测试样例

输入:arr = [1, 2, 4, 7, 11, 15] ,target = 6
输出:[1, 2, 4]

在该样例中target6,对于数字1数组中没有5能使其满足和6,因此跳过。对于数字2而言数组中存在数字4使其满足和为6。因此答案为[1,2,4],其中1代表在数组中能够找到这样的两个数使其满足target的条件,这两个数字是24

输入:arr = [1, 3, 5, 8, 12] ,target = 10
输出:[0, 0, 0]

在该样例中不存在两个数满足target10的条件,因此答案为[0,0,0]

输入:arr = [-17, -9, -6, -3, 1, 8, 8, 11, 13, 13, 14, 16, 17] ,target = 2
输出:[1, -9, 11]

在该样例中-9, 11-6, 8都满足和为2,但由于-9-6在数组中更靠前,因此答案是[-1,-9,11]

解题思路

一个思路就是用两层循环嵌套暴力求出答案,但对于长度很长的数组N^2的时间复杂度太高了。因此可以考虑用空间换时间的方法,使用一个map保存已经遍历过的数字利用哈希表的特性O(1)的复杂度判断对应的target - x是否存在,但是这样会带来一个问题就是找到的数对不一定满足是数组中的第一对数。

例如测试样例中的第三个样例,当循环遍历到8的时候此时满足target的数是-6而不是答案的-9。这种方法下只能够满足数对中的第二个数是最早的数字,而不能满足第一个数字是最早出现的数字。因此为了满足第一个数字是最早出现的数字,需要对数组进行反向遍历并保留匹配到的最后一种情况,这样就能保证输出的是正序情况下的第一对数。

def solution(arr: list, target: int) -> list:
    # 用dict保存数字是否出现过,如果cnt[num] = 1就是出现过
    cnt = {}
    # 默认为没找到的情况
    ans = [0,0,0]
    #倒序遍历arr
    for i in arr[::-1]:
        #找到数对的情况更新ans
        if target - i in cnt:
            ans = [1, i, target - i]
        cnt[i] = 1
    #返回答案
    return ans

复杂度分析

空间复杂度: 使用dictarr里出现的数字,空间复杂度上为O(N)。 时间复杂度: 对数字倒序遍历一次,空间复杂度上为O(N)