算法练习day7

四数相加II

代码随想录 0454.四数相加II

454. 四数相加 II - 力扣(LeetCode)

(用时:0.5小时)

思路

本道题是需要在四个数组中,各找一个数,这些数加起来能够等于0,那么就是答案元组。各个数组的数字元组中的位置是固定的,0001和1000是不同的答案。

普通的解法一般是四重循环遍历,逻辑简单粗暴就不再赘述。

这道题可以用哈希表配合进行求解。

  • 先算前两个数组元素相加的结果,将他们的结果存入哈希表中,这里是一个二重循环。

    对于前两个数而言,1 2和2 1他们的和虽然都是3,但是情况是不一样的,属于3的情况出现了两次。题目要输出答案元组的个数,因此选择使用hashset。

  • 接着再算后两个数组元素相加结果,通过hashset查找前两个数的和中符合条件的,组成一个完整的答案元组。在此过程中用计数器累加即可。

错误

思路理解的差不多,但是在写的时候,一些细节方面还是出了问题:

  1. 累加时,累加的数值出现问题。

  2. (疑问)hashset的key和value取什么

个人理解如下:

  • (疑问)hashset的key和value取什么

    hashset是用来记录前两个数字的和出现情况的。那么key应该是两个数字的和,value应该是这个和出现的频率(次数)。

  • 累加时,累加的数值出现问题。

    前面说了,hashset记录的是前两个数字的和出现的频率,那么在累加的时候,应该是要加上频率(次数)而非单纯的加一。

代码实现

hashset实现:

public int FourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4)
{int ans = 0, temp;Dictionary<int, int> dic = new Dictionary<int, int>();
​//记录前两位相加的结果出现的频率foreach (int num1 in nums1){foreach (int num2 in nums2){if(dic.ContainsKey(num1 + num2)){dic[num1 + num2]++;}else{dic.Add(num1 + num2, 1);}}}
​//计算后两位相加的结果,通过这个结果与最终结果的差值查找是否有前两位的和匹配foreach(int num3 in nums3){foreach(int num4 in nums4){temp = 0 - num3 - num4;
​if(dic.ContainsKey(temp)){ans+= dic[temp];}}}
​return ans;
}

赎金信

代码随想录 0383.赎金信

383. 赎金信 - 力扣(LeetCode)

(用时:0.3小时)

思路

本题和前面一道四数相加II有点像,只是这道题的变成了两个。

magazine 中的每个字符只能在 ransomNote 中使用一次,那么就不是查看元素出现的频率,而是单纯查看是否出现即可。

字母一共26个(题目假设只看小写)并不多,故用数组实现哈希表。

错误

这道题是比较简单的题,但是在一些细节方面还是出了问题:

  1. 看错题,以为是要查看字母出现的频率。

  2. 要先处理magazine再处理ransomNote。

个人理解如下:

  • 看错题,以为是要查看字母出现的频率。

    这个问题就没什么好说的了。。。查看字母的频率用键值对结构(dictionary)、查看字母是否出现用hashset。数组结构两种都可以用,用数组要看这个表会有多大。

  • 要先处理magazine再处理ransomNote。

    题目意思是检验ransomNote的字母在magzine的情况(magazine 中的每个字符只能在 ransomNote 中使用一次)。那么magzine要么是包含ransomNote的关系(返回true),要么就是不匹配的关系(返回false)。

    先得得到magzine的元素,再探究ransomNote所有的元素是否在ransomNote出现,且magzine的字母只用一次。

代码实现

/// <summary>
/// 哈希数组实现
/// </summary>
/// <param name="ransomNote"></param>
/// <param name="magazine"></param>
/// <returns></returns>
public bool CanConstruct(string ransomNote, string magazine)
{int[] hash = new int[26];
​for (int i = 0; i < magazine.Length; i++){hash[magazine[i] - 'a']++;}
​for (int i=0;i<ransomNote.Length;i++){hash[ransomNote[i] - 'a']--;}
​for (int i=0;i<hash.Length;i++){if (hash[i]<0){return false;}}
​return true;
}

三数之和

代码随想录 0015.三数之和

15. 三数之和 - 力扣(LeetCode)

(用时:1小时)

思路

和前面的四数相加II不同,本道题是在一个数组中找答案,答案元组不能重复(例如123 和321其实是一个元组)

本题的重点在于去重。

题目是在哈希表章节出现的,去重、唯一性第一反应是用哈希表做。卡哥并没有讲解哈希的方法,因为去重很麻烦

  • 哈希的思路应该是先求出前两项a+b的和,再通过答案和哈希表查找第三项c是否存在。

  • 哈希的结构中,hashset是只记录是否存在,不记录存在次数的,那么可能出现,1 2 1,而1只出现过一次,同一个元素被多次使用。此时感觉可以用键值对的类型来记录出现次数?

  • 但是如果要记录次数,就得配合其他的变量使用。比如让某个数字使用了一次值就--,这是循环一轮时的操作,在新一轮的值又得恢复原本的值。。。这里就很麻烦。

  • 此外,用记录出现次数的键值对类型来做也要额外去重(这里就是卡哥说的去去重麻烦),额外对答案列表中重复的元组去重。

  • 去重的方式其实就是来个二重循环,定一个元组,然后对其他的元组进行遍历比较。这里元组中数字的顺序还不一样,意味着if的条件不能单纯的num1[i]==num2[i]这种,还得处理。

卡哥讲授的是双指针的方法。

  • 一重循环探索确定第一项数字a。

  • 循环中用left和right分别对数字a后的区域进行收缩判断。

  • 这个方法的数组要是有序的。

  • 这中间加上数字a的去重和剪枝操作。

总结来说:

  • 先对数组排序,这里的思路是认为数组升序。

  • 排序后,最外层的循环遍历数字a的情况。

    遍历过程中对数字a进行去重,如果此时a的数值已经出现过了,那就向后遍历(因为是有序的,重复的数字会连续出现)。

    还可以对数字a剪枝。题目的和固定为是0,那么如果数字a大于0,那么该数组不可能会有答案元组(因为是升序的,数字a是三个数字中最小的)

  • 在确定数字a后,用left和right分别表示数组后续剩下的区域,对这块区域进行收缩。

  • 收缩过程中,如果找到了合适的值就可保留下来。

    若nums[i] + nums[left] + nums[right] == 0,表示这组答案是可以的,记录下来即可,然后两个指针一起收缩。 若<0,表示目前的有值有点小,那么让left++即可(数组升序) 若>0,表示目前的有值有点大,那么让right--即可(同理)

  • 收缩过程中,要对left和right对应的值进行去重。

    相同的数值是连续出现的,让left和right指向的值和相邻值不同,即可达到去重的目的。

    需要注意的是,去重是在该答案已经有了的情况下才需要对left和right接下来的值进行去重。这说明left和right的去重是要在答案元组被记录下来后的(卡哥提到的“先记录下来再去重”)

疑问点

看完视频和讲解,对解法还是有一些质疑:

  1. 疑问1:为什么找到答案时,双指针同时收缩?

  2. 疑问2:right和left的去重逻辑和双指针收缩顺序的问题?

  3. 疑问3(错误):数字a的剪枝

个人理解如下:

  • 为什么找到答案时,双指针同时收缩?

    找到答案后,i、left和right的值都是固定的。如果只是收缩left或right,加法式子中其中两个加数不变,那么另一个加数的值也应该是固定的,那么此时这组答案应该有了就重复了。

  • right和left的去重逻辑和双指针收缩顺序的问题?

    这里个人认为放在前后都行。

    卡哥是先去重,再收缩。收缩比较的是left和left+1(right和right-1)。我个人是right和left的去重逻辑放在双指针收缩前,收缩比较的是left和left-1(right和right+1)。这里顺序与收缩逻辑对应一下就可以了。

  • 数字a的剪枝

    这里在写程序时也出现了错误(但是因为是前一天做的,现在忘了这里是怎么错的。。。放上来当作巩固吧)。结果要求是0,数组是升序,那么如果第一个数都大于了0,此数组中想要三个数相加为0是无解的。

代码实现

双指针法:

/// <summary>
/// 双指针法
/// </summary>
/// <param name="nums"></param>
/// <returns></returns>
public IList<IList<int>> ThreeSumFun1(int[] nums)
{IList<IList<int>> ans = new List<IList<int>>();int left, right;
​Array.Sort(nums);
​for (int i = 0; i < nums.Length; i++){if (nums[i] > 0) return ans;
​if (i > 0 && nums[i] == nums[i - 1]) continue;
​left = i + 1;right = nums.Length - 1;
​while (left < right){if (nums[i] + nums[left] + nums[right] == 0){ans.Add(new List<int> { nums[i], nums[left], nums[right] });left++;right--;
​while (left < right && nums[left] == nums[left - 1]) left++;while (left < right && nums[right] == nums[right + 1]) right--;}else if (nums[i] + nums[left] + nums[right] < 0){left++;}else{right--;}}
​}return ans;
}

四数之和

代码随想录 0018.四数之和

18. 四数之和 - 力扣(LeetCode)

(用时:2小时)

思路

这道题的思路是在前一道三数之和的基础上的。

三数之和中,哈希法太过复杂,因此卡哥优先讲解的是双指针法,这道题依旧使用的是双指针法。由于多了一个数,因此循环需要多加一层。

本道题就是先确定前两个数字ab,然后依旧用left和right收缩。

错误

写的时候错了一些:

  1. 错误1:b剪枝操作的返回值出了问题

个人理解如下:

  • b剪枝操作的返回值出了问题

    在三数之和时,只有一层循环因此在剪枝时,直接让整个函数返回列表也是可以的。这个想法延续要了四数之和,四数之和的第一层循环是和三数一样,因此没有出问题,但是第二层循环不能这么写。

    以力扣报错的 -3, -2, -1, 0, 0, 1, 2, 3 这组数据为例。一共是8组答案,程序只判断出了7组,落了一组。经过调试,发现是在-2 0 0 2 这组答案出现后,后面一组的答案没有出现,下图是出现问题前记录的一组答案:

    image-20240510121123236

    接着往后继续调试,在某一步中,发现第二层循环对b的剪枝操作让函数直接跳出了。

    image-20240510121256764

    查看后发现,i和j下标对应的数组值相加后恰好大于target且他们也大于0。但是后续的-1 0 0 1也是一组答案,这里由于b剪枝的原因直接跳过了。这里就是问题所在。

    image-20240510121339577

代码实现

双指针法:

/// <summary>
/// 双指针法
/// </summary>
/// <param name="nums"></param>
/// <param name="target"></param>
/// <returns></returns>
public IList<IList<int>> FourSumFun(int[] nums, int target)
{IList<IList<int>> ans = new List<IList<int>>();int left, right;
​Array.Sort(nums);for (int i=0;i<nums.Length;i++){//a剪枝操作if (nums[i] > 0 && nums[i] > target) break;
​//a去重操作if (i > 0 && nums[i] == nums[i - 1]) continue;
​for (int j=i+1;j<nums.Length;j++){//b剪枝操作if (nums[i] + nums[j] > 0 && nums[i] + nums[j] > target) break;
​//b去重操作if (j > i + 1 && nums[j] == nums[j - 1]) continue;
​left = j + 1;right = nums.Length-1;
​while(left<right){if (nums[i] + nums[j] + nums[left] + nums[right] == target){ans.Add(new List<int>() { nums[i], nums[j], nums[left], nums[right] });
​left++;right--;
​//去重while (left < right && nums[left] == nums[left - 1]) left++;
​//去重while (left < right && nums[right] == nums[right + 1]) right--;}else if (nums[i] + nums[j] + nums[left] + nums[right] < target){left++;}else{right--;}}}}
​
​return ans;
}

后记

前三道题是在昨天(5.9)写的,没来得及文字记录。最后一道题和文字记录都是今天(5.10)写的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/835508.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

onnx模型截取部分

这个是有需求的&#xff0c;比如有多个输入节点&#xff0c;我只用其中几个&#xff0c;或有多个输出节点&#xff0c;我只用其中几个。 比如这个输入&#xff0c;我们可以直接把transpose去掉&#xff0c;用类pytorch的N,C,H,W的格式输入。 还有如下输出&#xff1a; tran…

喜报|才聚荣获“2024年度PMI(中国)注册教育机构杰出机构奖”!

5月10日&#xff0c;“2024PMI&#xff08;中国&#xff09;注册教育机构合作伙伴大会”隆重举行&#xff0c;才聚集团受邀参加此次盛会。 本次大会就项目管理职业生态、发展趋势等热门问题进行了深入探讨分析。 PMP认证自1999年引入中国&#xff0c;为国家培养了大量项目管理…

Springboot+Vue项目-基于Java+MySQL的宠物商城网站系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

618有什么好物推荐?618平价好物清单,让你买到物超所值的好货!

618大促即将开启&#xff0c;大家是不是已经跃跃欲试&#xff0c;准备大肆采购一番了呢&#xff1f;别心急&#xff0c;让我为你揭晓几款数码、家居领域中的明星产品。这些好物不仅实用&#xff0c;而且性价比超高&#xff0c;让你在享受购物乐趣的同时&#xff0c;也能买到真正…

人工智能的未来:Sam Altman 揭穿搜索引擎谣言,调侃 ChatGPT 和 GPT-4 的“神奇”更新

人工智能的未来&#xff1a;Sam Altman 揭穿搜索引擎谣言&#xff0c;调侃 ChatGPT 和 GPT-4 的“神奇”更新 概述 科技界充斥着有关人工智能研究先驱组织 OpenAI 将推出类似谷歌搜索引擎的传言。然而&#xff0c;首席执行官 Sam Altman 已经平息了这些谣言&#xff0c;并透露…

mac 讨厌百度网盘怎么办

一、别拦我 首先请允许我泄个愤&#xff0c;tmd百度网盘下个1g的文件下载速度竟然超不过200k&#xff0c;只要不放在所有已打开软件的最前面&#xff0c;它就给你降到10k以内&#xff0c;关键是你慢就慢了&#xff0c;我也不是很着急&#xff0c;关键是你日常下载失败并且总是…

代码随想录算法训练营第36期DAY24

DAY24 235二叉搜索树的最近公共祖先 迭代法&#xff1a; /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solutio…

2024年5月10日有感复盘

2024年5月10日有感复盘 时间 今天是一个很美好的一天&#xff0c;原因是很平凡&#xff0c;读书很平凡&#xff0c;玩游戏很平凡&#xff0c;然后生活很平凡&#xff0c;未来可期&#xff0c;听歌很舒服&#xff0c;很喜欢一个人呆在图书馆的感觉&#xff0c;很喜欢发呆&…

DeepMind的首席执行官Demis Hassabis表示,未来一到两年内,能够独立完成复杂任务的AI代理将成为现实

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

网络安全复习

概述 重要性 网络安全威胁 OSI安全体系结构 信息与网络安全目标 机密性完整性可用性 五类安全服务 八类安全机制 网络安全体系结构 基本安全设计原则 数据加密技术 2.1数据加密技术概述 2.2经典加密 2.3对称秘钥加密 2.4公开秘钥加密 Diffie-Hellman秘钥交换 对称…

【DDR 终端稳压器】Sink and Source DDR Termination Regulator [B]

正式从这里开始 TI 的选型&#xff1b; tps54116-q1 tps51200a-q1 TPS53317 典型电路 pin功能EN对于 DDR VTT 应用&#xff0c;请将 EN 连接到 SLP_S3 对于任何其他应用&#xff0c;请使用 EN 作为 ON/OFF 功能 始终保持 EN 电压等于或低于 VIN 电压GND信号接地 连接到输…

活字格中读取粘贴板中的内容:剪切板cp,我手机就吃这一亲!

哟,小伙伴们,今天我们来聊聊一个有趣的小功能吧! 你们应该都熟悉"复制粘贴"这个操作了吧?用CtrlC和CtrlV就可以将文字或图片等内容从一处复制到另一处,方便极了。但是,如果你的设备没有键盘,就没法使用快捷键了,那可怎么办呢? 别急,我们有解决办法!开发应用的时候…

【复利思维 + 项目成功方程式】用1年,超越别人38年!

复利思维—每天进步1%。 一年后会比现在的自己优秀38倍。在做任何事情时都要考虑&#xff0c;这件事是否能随着时间不断积累扩大&#xff0c;不能积累价值的事情要及时调整和止损。 在这个过程中&#xff0c;千万不要陷入心理暗示的陷阱&#xff0c;尤其是越想得到的&#xf…

JVM调参实践总结

JVM调优–理论篇从理论层面介绍了如何对JVM调优。这里再写一篇WIKI&#xff0c;尝试记录下JVM参数使用的最佳实践&#xff0c;注意&#xff0c;这里重点介绍HotSpot VM的调参&#xff0c;其他JVM的调参可以类比&#xff0c;但不可照搬。 Java版本选择 基于Java开发应用时&…

政安晨:【Keras机器学习示例演绎】(四十二)—— 使用 KerasNLP 和 tf.distribute 进行数据并行训练

目录 简介 导入 基本批量大小和学习率 计算按比例分配的批量大小和学习率 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在…

机器学习求数组的迹

机器学习求数组的迹、也叫求矩阵的迹。 矩阵的迹&#xff0c;也称为迹数&#xff0c;是矩阵主对角线上所有元素的和。矩阵的迹具有以下重要性质&#xff1a;- 不变性&#xff1a;矩阵的迹在转置、加法、乘法等运算下保持不变。- 特征值关系&#xff1a;一个方阵的迹等于其所有特…

高标准农田建设项目天空地一体化智慧监管平台

一、建设背景 党中央、国务院高度重视高标准农田建设。国务院办公厅印发的《关于切实加强高标准农田建设提升国家粮食安全保障能力的意见》 明确提出&#xff0c;大力推进高标准农田建设&#xff0c;到2022年&#xff0c;建成10亿亩高标准农田&#xff0c;以此稳定保障1万亿斤以…

《C语言文件处理:从新手到高手的跃迁》

&#x1f4c3;博客主页&#xff1a; 小镇敲码人 &#x1f49a;代码仓库&#xff0c;欢迎访问 &#x1f680; 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&#x1f3fd;留言 &#x1f60d;收藏 &#x1f30f; 任尔江湖满血骨&#xff0c;我自踏雪寻梅香。 万千浮云遮碧…

寻找最大价值的矿堆 - 矩阵

系列文章目录 文章目录 系列文章目录前言一、题目描述二、输入描述三、输出描述四、Java代码五、测试用例 前言 本人最近再练习算法&#xff0c;所以会发布一些解题思路&#xff0c;希望大家多指教 一、题目描述 给你一个由’0’(空地)、‘1’(银矿)、‘2’(金矿)组成的地图…

Spring Cloud Gateway 全局过滤器

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 全局过滤器作用于所…