哈希表 | 1. 两数之和、454. 四数相加 | 用`字典key-value`最合适 | leecode刷题笔记

跟随carl代码随想录刷题
语言:python


454.四数相加为四个独立的数组,只要找到A[i] + B[j] + C[k] + D[l] = 0就可以,不用考虑重复问题。而18. 四数之和15.三数之和是一个数组(集合)里找到和为0的组合,可就难很多了!——代码随想录


1. 两数之和

题目:给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 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]

题目分析

🙋为什么要用哈希表
💁因为需要一个集合来存放遍历过的元素,然后在遍历的时候,如果想要找的元素在集合里出现过,则配对成功。因此首选哈希表

🙋为什么要用字典,而不用数组集合set
💁因为

  1. 数组中的元素由两个部分组成:索引下标元素值。本题中,我们不仅需要配对元素值,还要返回其对应的下标,因此需要同时记录这两部分内容,只有字典满足要求。
  2. 题目中允许我们按任意顺序返回结果,即不要求有序,所以使用字典效率更高。

🙋字典在本题中主要用于做什么?
💁记录我们访问过的元素。

⭐️本题中,元素值存储为key,索引下标存储为value{key:数据元素,value:数组元素对应的下标}

完整代码如下

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        record = {}
        for i in range(len(nums)):
            if nums[i] not in record:
                record[nums[i]] = i

            # 目标值如果存在于集合总,就配对成功
            num = target-nums[i]  # 目标值
            # 如果目标值在记录中,并且与当前元素的下标不同,则配对成功
            if (num in record) and (record[num] != i):return [i, record[num]]

用枚举的方法,直接查看元素值与下标

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        record = dict()

        for index, val in enumerate(nums):
            if target - val not in record:
                record[val] = index
            else:
                return [index, record[target - val]]

注意:是for idx, val in enumerate():,先是索引,然后是值!
而不是for val, idx in enumerate():

454. 中等四数相加 II

题目:给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:
0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
👉示例 1:
输入:nums1 = [1,2], nums2 = [-2,-1], nums3 = [-1,2], nums4 = [0,2]
输出:2
解释:
两个元组如下:

  1. (0, 0, 0, 1) -> nums1[0] + nums2[0] + nums3[0] + nums4[1] = 1 + (-2) + (-1) + 2 = 0
  2. (1, 1, 0, 0) -> nums1[1] + nums2[1] + nums3[0] + nums4[0] = 2 + (-1) + (-1) + 0 = 0

👉示例 2:
输入:nums1 = [0], nums2 = [0], nums3 = [0], nums4 = [0]
输出:1

题目分析

完整代码如下

那些我写过的坑

class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        record_ab = {}
        count = 0
        n = len(nums1)

        # 初始化字典:`key = nums1[i]+nums2[j]`,初始化`value = 0`
        for i in range(n):
            for j in range(n):
                if nums1[i] + nums2[j] not in record_ab:
                    record_ab[nums1[i] + nums2[j]] = 0

        # 统计每个`key`出现的次数`value`
        for i in range(n):
            for j in range(n): 
                record_ab[nums1[i] + nums2[j]] += 1

        # 统计`0 - (nums3[i] + nums4[j])`是否等于上述record_ab中的`key`
        for i in range(n):
            for j in range(n):
                if 0 - (nums3[i] + nums4[j]) in record_ab:
                    count += record_ab[0 - (nums3[i] + nums4[j])] 
                    
        return count

突然注意到,我写麻烦了。其实,如果题目与索引无关,遍历时可以写为for n1 in nums1:,而不需要写成for i in range(len(nums1)):。修改后代码如下:

class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        record_ab = {}
        count = 0
        n = len(nums1)

        # 初始化字典:`key = n1+n2`,统计`value`
        for n1 in nums1:
            for n2 in nums2:
                if n1 + n2 not in record_ab:
                    record_ab[n1 + n2] = 0

        # 统计每个`key`出现的次数`value`
        for n1 in nums1:
            for n2 in nums2: 
                record_ab[n1 + n2] += 1

        # 统计`0 - (n3 + n4)`是否等于上述record_ab中的`key`
        for n3 in nums3:
            for n4 in nums4:
                if 0 - (n3 + n4) in record_ab:
                    count += record_ab[0 - (n3 + n4)] 
                    
        return count

上述两种写法有一个共同点:都是先初始化字典,然后再对value赋值。能不能直接进行keyvalue的赋值呢?🙋有,其实就是变更一下思路:如果出现过,就count+=1,如果没有出现过,就赋count=1

最终代码如下

class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        record_ab = dict()
        count = 0

        # 初始化字典:`key = n1+n2`,初始化`value`
        for n1 in nums1:
            for n2 in nums2:
                if n1 + n2 not in record_ab:
                    record_ab[n1 + n2] = 1
                else:
                    record_ab[n1 + n2] += 1

        for n3 in nums3:
            for n4 in nums4:
                if 0 - (n3 + n4) in record_ab:
                    count += record_ab[0 - (n3 + n4)] 
                    
        return count
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值