0001_Two-Sum【S】找出数组中两数之和为目标值的两个数的下标

  • JY:找出数组中两数之和为目标值的两个数的下标

1、循环 + 判断(不使用字典)

  • 不使用字典的方式(性能下降,非空间换时间)
from typing import List

class Solution:
    def twoSum(self, nums: List[int],
                  target: int) -> List[int]:
        for idx, num in enumerate(nums):
            if target - num in nums and nums.index(target - num) != idx:
                return [idx, nums.index(target - num)]


nums = [1, 8, 2, 7, 11, 15]
target = 9
res = Solution().twoSum(nums, target)
print(res)

2、循环 + 哈希表(字典)

  • 假设 n + m = target,如果n在数组中,且m也在数组中,则有对应的一组数满足条件。
  • 因此可以遍历数组中的每一个元素n,判断target - n是否在数组中,如果存在则返回target - nn的下标
  • 哈希表获取元素的复杂度是O(1),算法整体的复杂度为O(n)
from typing import List


class Solution:
    def twoSum(self, nums: List[int],
                  target: int) -> List[int]:
        mapping = {}
        for index, num in enumerate(nums):
            # jy: 只需找到一组满足条件的数值组合即可
            if target - num in mapping:
                return [mapping[target - num], index]
            mapping[num] = index
        # jy: 如果不存在满足要求的两个数, 则返回 [-1, -1] 
        return [-1, -1]


nums = [2, 7, 11, 15]
target = 9
res = Solution().twoSum(nums, target)
print(res)

3、算法进阶:找出 nums 列表中所有和为 target 的组合

  • 在解法 1 的基础上,碰到符合要求的一对数后将其加入列表,并将其从 mapping 中剔除,防止重复使用
  • 如果要求符合要求的一对数不能相同,则可进一步定义一个集合,用于存储满足要求的一对数,后续再次碰到满足要求的一对数的其中一个数时,只需判断该数是否在该集合中,如果已经在该集合中,表明基于该数构成的一对满足要求的数已经存在,直接跳过即可。
from typing import List


class Solution:
    def twoSum(self, nums: List[int], target: int,
                  deduplicate=True) -> List[int]:
        """
        deduplicate: 为 True 时, 组合中同一个数值不重复使用
        """
        mapping = {}
        ls_res = []
        # jy: 用于记录已经确认过满足要求的一对数(记录之后, 后续方便去重)
        set_done = set()
        for index, num in enumerate(nums):
            #if target - num in mapping:
            if target - num in mapping and target - num not in set_done:
                # jy: 将目标下标值存储到 ls_res, 并从 mapping 中剔除
                #     防止相同数值后续重复使用
                ls_res.append([mapping.pop(target - num), index])
                # jy: 如果要求去重, 则已经得到过的一对数要添加
                #     到 set_done 集合中
                if deduplicate:
                    set_done.add(target - num)
                    set_done.add(num)
            else:
                mapping[num] = index
        return ls_res


nums = [1, 8, 2, 7, 11, 5, 4, 5, 4, 15, 9, 0, 9, 0]
target = 9
res = Solution().twoSum(nums, target)
# jy: [[0, 1], [2, 3], [5, 6], [10, 11]]
print(res)


res = Solution().twoSum(nums, target, False)
# jy: [[0, 1], [2, 3], [5, 6], [7, 8], [10, 11], [12, 13]]
print(res)


nums = [1, 5, 2, 4, 3, 3, 3, 5, 4, 3, 3]
target = 6
res = Solution().twoSum(nums, target)
# jy: [[0, 1], [2, 3], [4, 5]]
print(res)


res = Solution().twoSum(nums, target, False)
# jy: [[0, 1], [2, 3], [4, 5], [6, 9]]
print(res)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

融码一生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值