算法训练营第五天 | 454.四数相加II\ 383. 赎金信\15. 三数之和\ 18. 四数之和

454.四数相加II

题目

思路与解法

第一想法:
carl的讲解: 前两个为一组,后两个为一组。遍历前两个可能的加值,再在后两组中寻找有没有前面值的负值,若有就是一组。

我认为,重点在于将问题简化为前两个数组和后两个数组的逻辑。

python 复制代码
class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        from collections import defaultdict
        sum_dict = defaultdict(int)
        for a in nums1:
            for b in nums2:
                sum_dict[a+b] += 1
        count = 0
        for c in nums3:
            for d in nums4:
                if (0-c-d) in sum_dict:
                    count += sum_dict[0-c-d]
        return count 

383. 赎金信

题目

思路与解法

第一想法: 将magazine中的字母存在字典中,key是字母,value是出现的次数。然后遍历ransomNote的字母,在magazine字典中出现一次就value减一,value小于0就返回False。若字典中没有,就直接返会False。最后都通过了,就返回True。

python 复制代码
class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        from collections import defaultdict
        magazine_dict = defaultdict(int)
        for a in magazine:
            magazine_dict[a] += 1
        for b in ransomNote:
            if b not in magazine_dict:
                return False
            magazine_dict[b] -= 1
            if magazine_dict[b] < 0:
                return False
            
        return True

15. 三数之和

题目

思路与解法

第一想法: 双指针,三个数,for i in enumerate(nums),i代表第一个,low = i+1, fast = low+1,代表后面两个。然后low 和 fast遍历数组来和i相加看是不是等于0。i也不断往后遍历。

但是忽略了去重。加上去重就是对的,但是超时了。

python 复制代码
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        res = []
        nums.sort()
        for i, num  in enumerate(nums):
            low = i + 1
            if i > 0 and nums[i] == nums[i-1]:
                continue
            while low < len(nums) -1 :
                fast = low + 1
                while fast < len(nums):
                    if nums[low] + nums[fast] + num == 0:
                        res.append([num, nums[low], nums[fast]])
                    while fast + 1 < len(nums) and nums[fast + 1] == nums[fast]:
                        fast += 1
                    fast += 1
                while low + 1 < len(nums) -1 and nums[low+1] == nums[low]:
                    low += 1
                low += 1
        return res
        

carl的讲解: 让fast指针从最右边开始,因为排序了,所以fast(right)指向的是最大值

python 复制代码
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        result = []
        nums.sort()
        
        for i in range(len(nums)):
            # 如果第一个元素已经大于0,不需要进一步检查
            if nums[i] > 0:
                return result
            
            # 跳过相同的元素以避免重复
            if i > 0 and nums[i] == nums[i - 1]:
                continue
                
            left = i + 1
            right = len(nums) - 1
            
            while right > left:
                sum_ = nums[i] + nums[left] + nums[right]
                
                if sum_ < 0:
                    left += 1
                elif sum_ > 0:
                    right -= 1
                else:
                    result.append([nums[i], nums[left], nums[right]])
                    
                    # 跳过相同的元素以避免重复
                    while right > left and nums[right] == nums[right - 1]:
                        right -= 1
                    while right > left and nums[left] == nums[left + 1]:
                        left += 1
                        
                    right -= 1
                    left += 1
                    
        return result

18. 四数之和

题目

思路与解法

carl的讲解:

python 复制代码
class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        nums.sort()
        n = len(nums)
        result = []
        for i in range(n):
            if nums[i] > target and nums[i] > 0 and target > 0:# 剪枝(可省)
                break
            if i > 0 and nums[i] == nums[i-1]:# 去重
                continue
            for j in range(i+1, n):
                if nums[i] + nums[j] > target and target > 0: #剪枝(可省)
                    break
                if j > i+1 and nums[j] == nums[j-1]: # 去重
                    continue
                left, right = j+1, n-1
                while left < right:
                    s = nums[i] + nums[j] + nums[left] + nums[right]
                    if s == target:
                        result.append([nums[i], nums[j], nums[left], nums[right]])
                        while left < right and nums[left] == nums[left+1]:
                            left += 1
                        while left < right and nums[right] == nums[right-1]:
                            right -= 1
                        left += 1
                        right -= 1
                    elif s < target:
                        left += 1
                    else:
                        right -= 1
        return result
相关推荐
稚辉君.MCA_P8_Java22 分钟前
Gemini永久会员 C++返回最长有效子串长度
开发语言·数据结构·c++·后端·算法
京东零售技术1 小时前
下一代 Lakehouse 智能未来新引擎 | Apache Hudi Meetup亚洲站活动回顾
算法
京东零售技术1 小时前
NeurIPS 2025 | TANDEM:基于双层优化的数据配比学习方法
后端·算法
zmzb01031 小时前
C++课后习题训练记录Day42
开发语言·c++·算法
CoovallyAIHub1 小时前
MAR-YOLOv9:革新农业检测,YOLOv9的“低调”逆袭
深度学习·算法·计算机视觉
Mr Lee_1 小时前
Smali 文件生成dex装箱算法整合
开发语言·python·算法
LDG_AGI1 小时前
【推荐系统】深度学习训练框架(十三):模型输入——《特征索引》与《特征向量》的边界
人工智能·pytorch·分布式·深度学习·算法·机器学习
CoovallyAIHub2 小时前
如何让SAM3在医学图像上比专用模型还强?一个轻量Adapter如何让它“秒变”专家?
深度学习·算法·计算机视觉
suoge2232 小时前
热传导控制方程有限元弱形式推导-有限元编程入门
算法
希望有朝一日能如愿以偿2 小时前
力扣每日一题:统计梯形的数目
算法·leetcode·职场和发展