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

[豪の算法奇妙冒险] 代码随想录算法训练营第七天 | 454-四数相加II、383-赎金信、15-三数之和、18-四数之和

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


LeetCode454 四数相加II

题目链接:https://leetcode.cn/problems/4sum-ii/description/

文章讲解:https://programmercarl.com/0454.四数相加II.html

视频讲解:https://www.bilibili.com/video/BV1Md4y1Q7Yh/?vd_source=b989f2b109eb3b17e8178154a7de7a51

​ 题目要求解有多少个元组(i,j,k,l)能满足nums1[i] + nums2[j] + nums3[k] + nums4[l] = 0,不用去重,既可以分成两组

​ 首先先用两层for循环遍历 nums1 和 nums2 数组,统计所有 nums1[i] + nums2[j] 和对应次数,用HashMap存储,Key为 nums1[i] + nums2[j] ,Value为出现的次数

​ 要想找到符合 nums1[i] + nums2[j] + nums3[k] + nums4[l] = 0 的情况次数,即在两层for循环遍历 nums3 和 nums4 数组时,累加所有HashMap中出现 0 - nums3[k] - nums4[l] 的情况对应的次数,即为最终答案

image-20251125204137286

class Solution {public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {HashMap<Integer,Integer> ab = new HashMap<Integer,Integer>();for(int i = 0;i < nums1.length;i++){for(int j = 0;j < nums2.length;j++){int sum = nums1[i] + nums2[j];if(ab.containsKey(sum)){int cnt = ab.get(sum) + 1;ab.replace(sum, cnt);}else{ab.put(sum, 1);}}}int result = 0;for(int i = 0;i < nums3.length;i++){for(int j = 0;j < nums4.length;j++){int target = 0 - (nums3[i] + nums4[j]);if(ab.containsKey(target)){result += ab.get(target);}}}return result;}
}

LeetCode383 赎金信

题目链接:https://leetcode.cn/problems/ransom-note/description/

文章讲解:https://programmercarl.com/0383.赎金信.html

​ 一拿到题目,首先想到的思路是先用HashMap,一层for循环遍历magazine字符串,统计magazine中出现的所有字符和对应次数

​ 然后再一层for循环遍历ransomNote字符串,每个字符去HashMap中查找是否存在,若存在则次数减一,减到零则移除映射关系;若不存在,则返回false;全部遍历完则返回true

​ 但是这个执行用时有点感人...因为用的是HashMap

​ 题目提示中说了 ransomNote 和 magazine 由小写英文字母组成,其实能用一维数组代替HashMap,这样在数据量大的时候处理效率会更优,用时更少

image-20251125205742647

class Solution {public boolean canConstruct(String ransomNote, String magazine) {HashMap<Character, Integer> dict = new HashMap<Character, Integer>();for(int i = 0;i < magazine.length();i++){char ch = magazine.charAt(i);if(dict.containsKey(ch)){int cnt = dict.get(ch);dict.replace(ch, cnt+1);}else{dict.put(ch, 1);}}for(int i = 0;i < ransomNote.length();i++){char target = ransomNote.charAt(i);if(dict.containsKey(target)){int cnt = dict.get(target);if(cnt == 1){dict.remove(target);}else{dict.replace(target, cnt-1);}}else{return false;}}return true;}
}

LeetCode15 三数之和

题目链接:https://leetcode.cn/problems/3sum/description/

文章讲解:https://programmercarl.com/0015.三数之和.html

视频讲解:https://www.bilibili.com/video/BV1GW4y127qo/?vd_source=b989f2b109eb3b17e8178154a7de7a51

​ 梦破碎的地方hhh,一开始挺有思路,然后用哈希法越写越发觉不对劲,然后就一团浆糊,不知所措了...题目复杂在它需要去重!哈希法需要去重的细节很多,很不好做

​ 看了Carl哥的讲解后,发现双指针的解法也在去重上有着诸多细节。

​ 首先,先对原数组进行升序排序,这样负数在左侧,正数在右侧,采用i作为基底,left = i+1,right = nums.length-1,去寻找nums[i] + nums[left] + nums[right] = 0的三元组,若nums[i] + nums[left] + nums[right] > 0,则right往左移;若nums[i] + nums[left] + nums[right] < 0,则left往右移;若nums[i] + nums[left] + nums[right] = 0,则找到目标三元组

​ 接下来就是剪枝,剪枝策略是,nums[i] > 0的时候,直接结束寻找,因为之后都为正数,凑不到三数相加等于0的情况

​ 然后就是去重,当 nums[i] == nums[i-1]则continue,即对基底去重,不再收录重复的组合,这里操作了i-1,为了保证下标合法性,还要加上i>0的条件

​ 最后收割答案的时候也要去重,当获得一个要求的三元组时,为了防止重复收割此三元组,在right>left的情况下,若nums[right-1] == nums[right],则right--;同理,若nums[left] == nums[left+1],则left++。注意使用while去重此情况,而不是if

image-20251125221849871

class Solution {public List<List<Integer>> threeSum(int[] nums) {List<List<Integer>> result = new ArrayList<>();Arrays.sort(nums);for(int i = 0;i < nums.length;i++){if(nums[i] > 0){return result;}if(i > 0 && nums[i] == nums[i-1]){continue;}int left = i + 1;int right = nums.length - 1;while(left < right){int sum = nums[i] + nums[left] + nums[right];if(sum > 0){right--;}else if(sum < 0){left++;}else{List<Integer> temp = new ArrayList<>();temp.add(nums[i]);temp.add(nums[left]);temp.add(nums[right]);result.add(temp);while(left < right && nums[left] == nums[left+1]){left++;}while(left < right && nums[right] == nums[right-1]){right--;}left++;right--;}}}return result;}
}

LeetCode18 四数之和

题目链接:https://leetcode.cn/problems/4sum/description/

文章讲解:https://programmercarl.com/0018.四数之和.html

视频讲解:https://www.bilibili.com/video/BV1DS4y147US/?vd_source=b989f2b109eb3b17e8178154a7de7a51

​ 这题沿用三数之和那题的思路,只是外面多了一层for循环,且剪枝策略有所变化

​ 先对nums数组进行升序排序,然后两层for循环找k和i,里面再设置left和right。当 nums[k] + nums[i] + nums[left] + nums[right] > target 时,right左移;当 nums[k] + nums[i] + nums[left] + nums[right] < target 时,left右移;当 nums[k] + nums[i] + nums[left] + nums[right] = target时,收割结果集

​ 这题的剪枝策略是,当 nums[k] > target 且 nums[k] >= 0 时,结束最外层k循环;当 nums[k] + nums[i] > target && nums[k] + nums[i] >= 0 时,结束第二层i循环

​ 去重策略是,当 nums[k] == nums[k-1] 则continue,即对基底k去重,不再收录重复的组合,这里操作了k-1,为了保证下标合法性,还要加上k>0的条件;同样的,当 nums[i] == nums[i-1]则continue,即对基底i去重,不再收录重复的组合,这里操作了i-1,为了保证下标合法性,还要加上i>k+1的条件

​ 最后收割答案的时候也要记得去重,当获得一个要求的四元组时,为了防止重复收割此元组,在right>left的情况下,若nums[right-1] == nums[right],则right--;同理,若nums[left] == nums[left+1],则left++。注意使用while去重此情况,而不是if

image-20251126130730173

class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {List<List<Integer>> result = new ArrayList<>();Arrays.sort(nums);for(int k = 0; k < nums.length; k++){if(nums[k] > target && nums[k] >= 0){break;}if(k > 0 && nums[k] == nums[k-1]){continue;}for(int i = k+1; i < nums.length; i++){if(nums[k] + nums[i] > target && nums[k] + nums[i] >= 0){break;}if(i > k+1 && nums[i] == nums[i-1]){continue;}int left = i + 1;int right = nums.length - 1;while(left < right){long sum = (long) nums[k] + nums[i] + nums[left] + nums[right];if(sum > target){right--;}else if(sum < target){left++; }else{List<Integer> temp = new ArrayList<>();temp.add(nums[k]);temp.add(nums[i]);temp.add(nums[left]);temp.add(nums[right]);result.add(temp);while(left < right && nums[left] == nums[left+1]){left++;}while(left < right && nums[right] == nums[right-1]){right--;}left++;right--;}}}}return result;}
}
http://www.jsqmd.com/news/51488/

相关文章:

  • go2网线连接
  • 2025年评价高的功能五金奢适美学五金厂家最新权威推荐排行榜
  • 2025年热门的铝箔橡塑保温板厂家最新权威推荐排行榜
  • 2025年比较好的VR工厂远程云参观行业竞争力排行榜
  • ZT9101 无线网卡驱动下载(Windows/Linux/Android)
  • 2025年知名的加热管厂家最新推荐排行榜
  • 2025年AI写作工具终极评测:PaperRed、Claude、WPS AI等七大工具全面对比
  • 2025年热门的防爆加热器厂家最新推荐权威榜
  • why China is bad
  • 2025年知名的耐高温吸盘厂家推荐及选购参考榜
  • 2025年比较好的BOBBIN变压器骨架TOP实力厂家推荐榜
  • TRAE SOLO:基于React 18+与蓝耘MaaS的多语言智能翻译高效的平台设计与实现
  • 2025年知名的六角不锈钢螺栓TOP实力厂家推荐榜
  • 2025年比较好的不锈钢工艺展架热门厂家推荐榜单
  • 2025年比较好的高速贴标机最新TOP品牌厂家排行
  • 2025年评价高的沙漏包装亚克力管行业内知名厂家排行榜
  • 2025年比较好的单头离子风机优质厂家推荐榜单
  • 2025年优质的psa制氮机厂家选购指南与推荐
  • 2025年口碑好的不锈钢焊管热门厂家推荐榜单
  • 2025年热门的橱柜异型铰链厂家最新权威推荐排行榜
  • 2025年知名的马口铁盒厂家推荐及选购指南
  • why hangel is bad
  • 2025年口碑好的导电泡棉厂家推荐及采购指南
  • 2025年靠谱的高端卫浴收纳厂家推荐及选购指南
  • 2025年知名的化工螺杆真空泵厂家最新推荐排行榜
  • 2025年口碑好的大米磨面机厂家最新推荐排行榜
  • 2025年最大的杭州宠物医院排行榜推荐
  • 2025年质量好的面粉加工成套设备厂家实力及用户口碑排行榜
  • 2025年比较好的移动餐车小吃车全国热门厂家实力排名
  • 2025年口碑好的高性价比的电动车电池厂家选购指南与推荐