当前位置: 首页 > news >正文

代码随想录算法训练营第七天|454、两数相加II 383、赎金信 15、三数之和 18、四数之和

目录

454. 四数相加 II

题目描述

解题思路

易错点

复杂度分析

383. 赎金信

题目描述

解题思路

复杂度分析

15. 三数之和

题目描述

解题思路

复杂度分析

18. 四数之和

题目描述

解题思路

易错点

复杂度分析

哈希表总结


454. 四数相加 II

题目描述

  • 给你四个整数数组nums1nums2nums3nums4,数组长度都是n,请你计算有多少个元组(i, j, k, l)能满足:
  • 0 <= i, j, k, l < n
  • nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0

解题思路

  • 将nums3和nums4移到等式右边去,这样1+2 = - 3 - 4,记录1+2的和(此题找不同的下标,所以尽管元素可能相同但是下标不一样还是不同的组合),再计算-3-4看是否和他相等
  • 这样问题就转换成了判断-3-4是否在1+2的集合中存在,由此此题使用哈希

使用什么数据结构呢?

  • 数组:由题四个数组的取值范围很大,存放到数组里会造成极大的空间浪费
  • 集合:本题是用下标来进行统计,不能去重
  • 字典(映射):综上所述,该数据结构很合适
class Solution(object): def fourSumCount(self, nums1, nums2, nums3, nums4): cnt = defaultdict(int) for n in nums1: for m in nums2: cnt[n + m] += 1 ans = 0 for n in nums3: for m in nums4: ans += cnt[-n - m] if - n - m in cnt else 0 return ans

易错点

  • 计算ans时寻找的是cnt中-n-m的值,而不是m+n

复杂度分析

  • 时间复杂度

    • 有两个for循环,且数组长度都相同,O(n^2)
  • 空间复杂度

    • 主要是哈希表,最多存储了n * n组数据,O(n^2)

383. 赎金信

题目描述

  • 给你两个字符串:ransomNotemagazine,判断ransomNote能不能由magazine里面的字符构成。
  • 如果可以,返回true;否则返回false
  • magazine中的每个字符只能在ransomNote中使用一次。

解题思路

  • 同242. 有效的字母异位词
class Solution(object): def canConstruct(self, ransomNote, magazine): cnt = defaultdict(int) for r in ransomNote: cnt[r] += 1 for m in magazine: if m in cnt: cnt[m] -= 1 for c in cnt: if cnt[c] > 0: return False return True
class Solution(object): def canConstruct(self, ransomNote, magazine): return not Counter(ransomNote) - Counter(magazine)
class Solution(object): def canConstruct(self, ransomNote, magazine): return all(ransomNote.count(c) <= magazine.count(c) for c in set(ransomNote))

复杂度分析

  • 时间复杂度

    • 和字符串长度有关,O(m+n)
  • 空间复杂度

    • 字母只有26个,O(1)

15. 三数之和

题目描述

  • 给你一个整数数组nums,判断是否存在三元组[nums[i], nums[j], nums[k]]满足i != ji != kj != k,同时还满足nums[i] + nums[j] + nums[k] == 0。请你返回所有和为0且不重复的三元组。
  • 注意:答案中不可以包含重复的三元组。

解题思路

  • 三数之和,依旧可以转化为两数之和是否存在于-a中,但是由于哈希适合处理寻找元素的存在性,对于去重十分的繁琐

  • 由此,来使用双指针计算两数的和并与第一个数进行比较就是一个新的思路

  • 但是,在做题过程中,去重是这个题目最大的难题

  • 由此,我们可以将去重操作切割为三部分

    • 第一部分:首元素的去重,那么我们是用nums[i] == nums[i-1]还是用nums[i] == nums[i + 1]来进行判断呢?
      • 举个栗子,符合题意的数组为[-1,-1,2,4],此时i位于首地址,left指针指向-1,right指针指向2,如果使用后者,那么left指向2,right指向4,就跳过了一种可能情况,故选前者
    • 第二部分:left(第二个元素)的去重,只需要在找到目标集合后,对left+1即可
      • 举个栗子:此时数组为[-1,-1,-1,2],left指向第二个-1,right指向2,只需要对left+1即可跳过相同元素的情况
    • 第三部分:right(第三个元素)的去重,同上
class Solution(object): def threeSum(self, nums): ans = [] nums.sort() for i in range(len(nums)): #nums[0]为正数,后面全为正数,相加不可能等于0 if nums[i] > 0: break if i > 0 and nums[i] == nums[i - 1]: continue left = i + 1 right = len(nums) - 1 while right > left: if nums[right] + nums[left] > -nums[i]: right -= 1 elif nums[right] + nums[left] < -nums[i]: left += 1 else: ans.append([nums[i],nums[left],nums[right]]) while right > left and nums[left] == nums[left + 1]: left += 1 while right > left and nums[right] == nums[right - 1]: right -= 1 left += 1 right -= 1 return ans

复杂度分析

  • 时间复杂度

    • 排序:O(nlogn)
    • 外层循环O(n) +内层双指针O(n)--->O(n^2)
    • 总复杂度:O(n^2)
  • 空间复杂度

    • sort原地排序,空间复杂度为O(logn)
    • 总复杂度:O(logn)

18. 四数之和

题目描述

  • 给你一个由n个整数组成的数组nums,和一个目标值target。请你找出并返回满足下述全部条件且不重复的四元组[nums[a], nums[b], nums[c], nums[d]](若两个四元组元素一一对应,则认为两个四元组重复):
  • 0 <= a, b, c, d < n

  • abcd互不相同

  • nums[a] + nums[b] + nums[c] + nums[d] == target

  • 你可以按任意顺序返回答案 。

解题思路

  • 就是三数之和外面嵌套一层来增加一个数
class Solution(object): def fourSum(self, nums, target): ans=[] nums.sort() for i in range(len(nums)): 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,len(nums)): if nums[j] + nums[i] > target and target > 0: break if j > i + 1 and nums[j] == nums[j - 1]: continue left = j + 1 right = len(nums) - 1 while right > left: sum_ = nums[i] + nums[j] + nums[left] + nums[right] if sum_ > target: right -= 1 elif sum_ < target: left += 1 else: ans.append([nums[i],nums[j],nums[left],nums[right]]) while right > left and nums[left] == nums[left + 1]: left += 1 while right > left and nums[right] == nums[right - 1]: right -= 1 left += 1 right -= 1 return ans

易错点

  • 此题的目标值是target而不是0,在进行剪枝操作时,只有当数组内的数都为正数并且target>0才能去剪枝
    • 举个栗子,数组为[-2,-1,0,0,1,2],target = -3时,剪枝操作时-2>-3就会跳过这个情况,因为数相加并不一定是越加越大,为负数的时候也会越加越小

复杂度分析

  • 时间复杂度

    • 两层外循环O(n^2)+双指针O(n)--->O(n^3)
    • 排序:O(nlogn)
  • 空间复杂度

    • sort原地排序,空间复杂度为O(logn)
    • 总空间复杂度:O(logn)

哈希表总结

  • 哈希表是用来快速判断一个元素是否在集合里
  • 哈希表的数据结构(数组,set,map)各自适用的场景
http://www.jsqmd.com/news/541596/

相关文章:

  • Linux Ubuntu 24.04 Server 超简单部署 Fast GPT(新手零踩坑)
  • OpenClaw多模态扩展:nanobot镜像处理图片与文本混合任务
  • Rocky Linux 9.5离线环境保姆级教程:手把手搞定Docker 25.0.5完整部署
  • 循环队列在嵌入式消息处理中的实现与应用
  • 4重防护构建安卓安全屏障:APKMirror应用管理全攻略
  • 《PyCharm 自定义背景图最简易教程,让你的编辑器颜值拉满!》
  • 2026论文写作工具红黑榜:AI论文平台怎么选?清单来了
  • CTFSHOW web入门 爆破 web23
  • 为什么3分钟搞懂AI
  • 【2026最新】IDEA 2025.3最新安装教程
  • 使命召唤系列合集COD 1-21部 中文版 全DLC+MOD修改器 PC单机联机游戏射击游戏
  • 破解语言壁垒:Translumo颠覆实时屏幕翻译的跨语言工具革命
  • 基于springboot数学库组卷系统设计与开发(源码+精品论文+答辩PPT等资料)
  • 零代码玩转OpenClaw:ollama-QwQ-32B自动化脚本生成教程
  • 浏览器窗口最小化的时候,setInterval 执行变慢,解决方案
  • GetQzonehistory终极指南:一键备份QQ空间所有历史说说完整教程
  • 2026工业加固计算机优质推荐榜适配极端工况 - 优质品牌商家
  • 终极Mac鼠标兼容性解决方案:如何用Mac Mouse Fix让第三方鼠标比苹果触控板更好用 [特殊字符]
  • YOLOv8-CopyPaste:基于复制粘贴增强的小目标与遮挡检测算法改进
  • 实战驱动:告诉快马你的vue项目类型,获取量身定制的环境与示例
  • Apache IoTDB Web Workbench:时序数据库可视化管理平台技术白皮书
  • 2026便携式加固计算机优质品牌推荐指南:工业加固计算机/工业平板电脑/工控机/无人机地面站加固计算机/选择指南 - 优质品牌商家
  • JAVA 国际版同城拼车系统源码 顺风车预约服务平台搭建全攻略
  • Bypass Paywalls Clean:3步搞定付费内容,你的免费阅读神器
  • 双模型灾备方案:OpenClaw同时接入ollama-QwQ-32B与云端API的实践
  • 傅里叶变换与拉普拉斯变换:从公式到工程应用的全面解析
  • 【基于Tube的非线性系统模型预测控制MPC】基于鲁棒控制不变集的管式模型预测控制方案及其在利普希茨非线性系统中的应用附Matlab代码
  • League-Toolkit:颠覆级英雄联盟全场景辅助工具,让你的上分效率提升300%
  • 【GitLab】告别“Ensure URL is HTTPS”错误:SSH与HTTPS协议配置全攻略
  • OpenClaw+GLM-4.7-Flash智能家居联动:自然语言控制IoT设备