哈希表 | 454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和

目录

454.四数相加II

题目链接: 454.四数相加II - 力扣(LeetCode)

文章讲解:代码随想录

视频讲解:学透哈希表,map使用有技巧!LeetCode:454.四数相加II

思路

  1. 暴力解,超时,时间复杂度为n^4
  2. 利用字典类哈希表优化为n^2

暴力解【超时】

python 复制代码
class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        hash1 = []
        for num1 in nums1:
            for num2 in nums2:
                hash1.append(num1+num2)
        hash2 = []
        for num3 in nums3:
            for num4 in nums4:
                hash2.append(num3+num4)
        count = 0
        for i in hash1:
            for j in hash2:
                if i+j == 0:
                    count += 1
        return count

字典类哈希表

python 复制代码
class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        hash1 = collections.defaultdict(int)
        for num1 in nums1:
            for num2 in nums2:
                hash1[num1+num2] += 1
        count = 0
        for num3 in nums3:
            for num4 in nums4:
                if -(num3+num4) in hash1:
                    count += hash1[-(num3+num4)]

        return count

383. 赎金信

题目链接: 383. 赎金信 - 力扣(LeetCode)

文章讲解:代码随想录

思路

  1. 类似 242.有效的字母异位词,用哈希表解决
  2. 利用python内置的Counter类优化

哈希表

python 复制代码
class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        hashtable = collections.defaultdict(int)
        for i in magazine:
            hashtable[i] += 1
        for j in ransomNote:
            hashtable[j] -= 1
        for k in hashtable.values():
            if k < 0 :
                return False
        return True

Counter类

python 复制代码
class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        return collections.Counter(ransomNote) <= collections.Counter(magazine)

15. 三数之和

题目链接: 15. 三数之和- 力扣(LeetCode)

文章讲解:代码随想录

视频讲解:梦破碎的地方!| LeetCode:15.三数之和

思路

  1. 暴力解,超时
  2. 将nums变成有序序列,固定第一个数,变成两数之和问题,使用相向双指针确定另外两个数【根据题意,需要注意去除重复答案】
  3. 进一步优化和剪枝

暴力解【超时】

python 复制代码
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        l = []
        for i in range(len(nums)-2):
            for j in range(i+1,len(nums)-1):
                for k in range(j+1,len(nums)):
                    if nums[i] + nums[j] + nums[k] == 0:
                        ll = [nums[i] , nums[j] , nums[k]]
                        ll.sort()
                        if ll not in l:
                            l.append(ll)
        return l

遍历+左右指针

python 复制代码
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        n = len(nums)
        l = []
        for i in range(n-2):
            if(i>0 and nums[i]==nums[i-1]):# 重复,就跳过这个值
                continue
            left = i+1
            right = n-1
            while left<right:
                if nums[i]+nums[left]+nums[right] == 0:
                    l.append([nums[i],nums[left],nums[right]])
                    left = left+1
                    while(left<right and nums[left]==nums[left+1]):#去重
                        left=left+1
                    right = right-1
                    while(left<right and nums[right]==nums[right-1]):#去重
                        right=right-1                    
                elif nums[i]+nums[left]+nums[right] < 0:
                    left = left+1
                else:
                    right = right-1
        return l

进一步优化

python 复制代码
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        n = len(nums)
        # 优化3
        if(not nums or n<3):
            return []
            
        nums.sort()        
        l = []
        for i in range(n-2):
            if(i>0 and nums[i]==nums[i-1]):#去重
                continue
            # 优化1:nums[i]和其他最小的两个数相加>0,则之后的情况全部都>0,break
            if nums[i]+nums[i+1]+nums[i+2]>0:
                break
            # 优化2:nums[i]和其他最大的两个数相加<0,则本循环的其他情况都<0,continue
            if nums[i]+nums[-1]+nums[-2]<0:
                continue
            left = i+1
            right = n-1
            while left<right:
                if nums[i]+nums[left]+nums[right] == 0:
                    l.append([nums[i],nums[left],nums[right]])
                    left = left+1
                    while(left<right and nums[left]==nums[left+1]):#去重
                        left=left+1
                    right = right-1
                    while(left<right and nums[right]==nums[right-1]):#去重
                        right=right-1                    
                elif nums[i]+nums[left]+nums[right] < 0:
                    left = left+1
                else:
                    right = right-1
        return l

18. 四数之和

题目链接: 18. 四数之和 - 力扣(LeetCode)

文章讲解:代码随想录

视频讲解:难在去重和剪枝!| LeetCode:18. 四数之和

思路

  1. 三数之和升级,解法一样

方法

python 复制代码
class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        n = len(nums)
        if n < 4:
            return[]
        
        nums.sort()
        l = []
        for i in range(n-3):
            if i>0 and nums[i] == nums[i-1]:
                continue
            for j in range(i+1,n-2):
                if j>i+1 and nums[j] == nums[j-1]:
                    continue
                value = target-nums[i]-nums[j]
                left = j+1
                right = n-1
                while left<right:
                    if nums[left] + nums[right] > value:
                        right -= 1
                    elif nums[left] + nums[right] < value:
                        left += 1
                    else:
                        l.append([nums[i], nums[j], nums[left], nums[right]])
                        left += 1
                        while left<right and nums[left] == nums[left-1]:
                            left += 1
                        right -= 1
                        while left<right and nums[right] == nums[right+1]:
                            right -= 1
        return l
相关推荐
业精于勤的牙17 分钟前
三角形最小路径和(二)
算法
风筝在晴天搁浅18 分钟前
hot100 239.滑动窗口最大值
数据结构·算法·leetcode
夏乌_Wx30 分钟前
练题100天——DAY31:相对名次+数组拆分+重塑矩阵
数据结构·算法
LYFlied30 分钟前
【算法解题模板】-解二叉树相关算法题的技巧
前端·数据结构·算法·leetcode
Ven%1 小时前
【AI大模型算法工程师面试题解析与技术思考】
人工智能·python·算法
天勤量化大唯粉1 小时前
枢轴点反转策略在铜期货中的量化应用指南(附天勤量化代码)
ide·python·算法·机器学习·github·开源软件·程序员创富
爱学习的小仙女!1 小时前
算法效率的度量 时间复杂度 空间复杂度
数据结构·算法
AndrewHZ1 小时前
【复杂网络分析】什么是图神经网络?
人工智能·深度学习·神经网络·算法·图神经网络·复杂网络
Swizard1 小时前
拒绝“狗熊掰棒子”!用 EWC (Elastic Weight Consolidation) 彻底终结 AI 的灾难性遗忘
python·算法·ai·训练
fab 在逃TDPIE2 小时前
Sentaurus TCAD 仿真教程(十)
算法