哈希表 | 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
相关推荐
汀、人工智能3 分钟前
[特殊字符] 第57课:搜索旋转排序数组
数据结构·算法·数据库架构·图论·bfs·搜索旋转排序数组
倦王7 分钟前
力扣日刷47
算法·leetcode·职场和发展
MicroTech20259 分钟前
突破量子数据加载瓶颈,MLGO微算法科技推出面向大规模量子计算的分治态制备技术
科技·算法·量子计算
码王吴彦祖11 分钟前
顶象 AC 纯算法迁移实战:从补环境到纯算的完整拆解
java·前端·算法
SccTsAxR16 分钟前
算法基石:手撕离散化、递归与分治
c++·经验分享·笔记·算法
wuweijianlove17 分钟前
算法测试中的数据规模与时间复杂度匹配的技术4
算法
Q741_14741 分钟前
每日一题 力扣 3655. 区间乘法查询后的异或 II 模拟 分治 乘法差分法 快速幂 C++ 题解
c++·算法·leetcode·模拟·快速幂·分治·差分法
The_Ticker42 分钟前
印度股票实时行情API(低成本方案)
python·websocket·算法·金融·区块链
夏乌_Wx1 小时前
剑指offer | 2.4数据结构相关题目
数据结构·c++·算法·剑指offer·c/c++
AI成长日志2 小时前
【笔面试算法学习专栏】哈希表基础:两数之和与字母异位词分组
学习·算法·面试