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

代码随想录算法训练营Day6 | Leetcode 454四数相加II383赎金15三数之和18四数之和 Leetcode454四数相加II383赎金15三数之和18四数之和解题思路与技巧、代码 阅读详情

● 454.四数相加II

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

解题思路:

第一轮遍历, 记录数组 nums1 和数组 nums2对应元素 之和 , 以及这样的和出现的次数, 记录在hashmap 中.

第二轮遍历,累加 nums3 和数组 nums4 对应元素 之和num,判断 数字0 与 和 num之前的差值,是否在hashmap 中 存在. 如果存在,记录次数,累加这些次数,进行返回.

参考答案:

class Solution {

public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {

HashMap<Integer, Integer> hashMap = new HashMap<>();

int index = 0;

for (int mum1 : nums1) {

for (int mum2 : nums2) {

if (hashMap.containsKey(mum1 + mum2)) {

hashMap.put(mum1 + mum2, hashMap.get(mum1 + mum2) + 1);

} else {

hashMap.put(mum1 + mum2, hashMap.getOrDefault(mum1 + mum2, 1));

}

}

}

int num = 0;

for (int mum3 : nums3) {

for (int mum4 : nums4) {

if (hashMap.containsKey(0 - (mum3 + mum4))) {

num += hashMap.get(0 - (mum3 + mum4)) ;

}

}

}

return num;

}

}

● 383. 赎金信

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

解题思路:

int num1 = 'a'; num1的值为97, 阿斯克码表的值.

int num2 = 'b' - 'a'; num2的值为1

int num2 = 'c' - 'a'; num2的值为2

创建一个长度为26 (小写字母的个数) 的数组.

小写字母,相比字母的顺序(a,b,c,d,e.......), 对应在阿斯克码表中的值是连续递增的.

单独的字符相减得到的数字,把他们映射到数组的索引位置上,根据映射到的次数,做增加操作.这样就有了字符串magazine的各个字母出现的位置 和 出现次数的对应关系了.

比如 'b'出现第一次在数字中 arr['b'-'a']++ ,也就是arr[1]=1.

再去遍历字符串ransomNote,映射到对应的次数,做减少次数的操作,抵消magazine之前的操作.

最后遍历数组,如果存在元素的值不为空,说明 字符串s 和t中存在字母出现的次数不一样,返回false; 否则true.

参考答案:

class Solution {

public boolean canConstruct(String ransomNote, String magazine) {

char[] chars = ransomNote.toCharArray();

int[] arr = new int[26];

for (char char1 : chars) {

arr[char1-'a']++;

}

char[] chars2 = magazine.toCharArray();

for (char char2 : chars2) {

arr[char2-'a']--;

}

for (int num : arr) {

if(num>0){

return false;

}

}

return true;

}

}

● 15. 三数之和

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

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

解题思路:

用双指针法来实现, 遍历数组, 声明三个变量 int i ; int left=i+1 ; int right = nums.length - 1

三个索引 i ; left ; right 处的值相加的和和 目标数字 0 相比,

i不变的时候,在,满足 left< right的情况,while 循环.

如果>0 ,右边指针right--;

如果<0 ,左边指针left++ ;

如果== 0,把对应数组的值记录在集合里面.

接下来分析,去重的问题.

题目要求: 数组不能重复; i ; left ; right 三个值也不能重复

i 的去重:

本题目是,先固定i,先移动 left 和right两个指针,来寻找满足和为0的三个值.

为什么是: nums[i] == nums[i -1] 而不是nums[i] == nums[i +1]

一组特殊的测试用例: [ -1,0,1 ] 排序后: [ -1,-1,0 ]

如果用后者的逻辑,这桑热书实际是满足要求的,数据不重复,但是数组内的元素可以是不同索引处的重复,用后面这个逻辑,就会把这组数据错过.

if (i>0 && nums[i] == nums[i -1]) {

continue;

}

left 和 right的去重:

(1). 三个值累加和 大于 或者 小于 0的时候,不满足等于条件,即使 nums[right] == nums[right - 1] 或者nums[left] == nums[left +1], 从 left 遍历到 left +1 或者从right 遍历到 right - 1 ,同样不满足等于0的条件,此时会 right-- 或者 left++ ,不用额外去重.

(2) . 三个值累加和 等于 0的时候,满足等于条件.

此时,如果 遇到 nums[right] == nums[right - 1] 或者nums[left] == nums[left +1]的情况,就要right-- 或者 left++. 此操作,在把满足条件的三个值存到集合中的代码 逻辑 之后.

参考答案:

class Solution {

public List<List<Integer>> threeSum(int[] nums) {

List<List<Integer>> list = new ArrayList<>();

Arrays.sort(nums);

int sum = 0;

for (int i = 0; i < nums.length; i++) {

int left = i + 1;

int right = nums.length - 1;

if (i>0 && nums[i] == nums[i -1]) {

continue;

}

while (left < right) {

sum = nums[i] + nums[left] + nums[right];

if (sum > 0) {

right--;

} else if (sum < 0) {

left++;

} else {

list.add(Arrays.asList(nums[i], nums[left], nums[right]));

while (right > left && nums[right] == nums[right - 1]) {

right--;

}

while (right > left && nums[left] == nums[left +1]) {

left++;

}

right--;

left++;

}

}

}

return list;

}

}

● 18. 四数之和

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

解题思路:

这个题目时在三数之和的基础上 变化了一下,思路还是相似的.

原来是一次for 循环, 遍历时的索引 i , 和 left ,right 三个变量对应处的数组的值,累加求和.

原来是对 i,和 left ,right 分别去重.

现在需要多一次 for循环,遍历时的索引 i , j, 和 left ,right 四个变量对应处的数组的值,累加求和.

现在是对 i, j 和 left ,right 分别去重.

参考答案:

class Solution {

public List<List<Integer>> fourSum(int[] nums, int target) {

Arrays.sort(nums);

List<List<Integer>> lists = new ArrayList<>();

long num = 0;

for (int i = 0; i < nums.length; i++) {

for (int j = i + 1; j < nums.length; j++) {

if(i>0 && nums[i]==nums[i-1]){

continue;

}

if(j >i + 1 && nums[j]==nums[j-1]){

continue;

}

int left = j + 1;

int right = nums.length - 1;

while (left < right) {

num = (long)nums[left] + nums[right] + nums[i] + nums[j];

if (left < right && num > target) {

right--;

} else if (left < right && num < target) {

left++;

} else {

lists.add(Arrays.asList(nums[left], nums[right], nums[i], nums[j]));

while (left<right && nums[left]==nums[left+1]){

left++;

}

while (left<right && nums[right]==nums[right-1]){

right--;

}

right--;

left++;

}

}

}

}

return lists;

}

}

代码随想录算法训练营Day07 | 454.四数相加II383. 赎金15. 三数之和18. 四数之和 阅读详情

相关推荐

具身智能中的(VLA)算法与实践——第一讲 基础与概览

本文介绍了视觉-语言-动作(VLA)模型的基础概念及其在AI领域的重要性。VLA模型通过融合多模态数据实现具身智能,使AI系统能感知环境并执行物理动作。文章探讨了大型语言模型(LLMs)和视觉语言模型(VLMs)如何赋能具身智能,包括指令解析、场景理解和动作规划。同时提供了Python、PyTorch/TensorFlow开发环境的详细搭建指南,包含GPU配置建议和测试代码。VLA模型在机器人操作、导航、人机协作等领域具有广泛应用前景,是实现通用人工智能的关键技术。

u012133341的博客 1554

代码随想录算法训练营第七 | 454.四数相加II383. 赎金15. 三数之和18. 四数之和

代码随想录算法训练营第七 | 454.四数相加II383. 赎金15. 三数之和18. 四数之和

qq_52421969的博客 1512

STM32G474使用HRTIM触发多路ADC采样,通过DMA传输,通过串口打印显示,实现PWM中间时刻采样,避免开关噪声

STM32G474使用HRTIM触发多路ADC采样,通过DMA传输,通过串口打印显示,实现PWM中间时刻采样,避免开关噪声,本工程使用CUBEIDE进行配置以及编译调试,使用的硬件为STM32G474官方开发板NUCLEO-G474RE

代码随想录算法训练营7 LeetCode 454.四数相加II 383. 赎金 15. 三数之和 18. 四数之和

这道题是典型的哈希题目,定义哈希表map,遍历nums1和nums2,计算两个数组中元素的和,并将和作为key,该和的出现次数作为value映射到map中。怎么记录该和出现的次数是一个难点,需要用到。直接上双指针,先对数组排序,for循环遍历数组,如果排好序的第一个元素已经>=0了,直接返回空数组。nums[i]+nums[left]+nums[right]的和,如果大于0,right--;用于将指定的元素转换为一个列表,由于底层是基于原始数组的,所以列表的大小是固定的,不能进行添加或删除元素的操作。

w1692013079的博客 364

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

哈希2,双指针法是重点

Ustianan的博客 2097

代码随想录算法训练营第六|454.四数相加II383.赎金15.三数之和18.四数之和

四数之和的双指针解法是两层for循环nums[k] + nums[i]为确定值,依然是循环内有left和right下标作为双指针,找出nums[k] + nums[i] + nums[left] + nums[right] == target的情况。首先定义 一个unordered_map,key放a和b两数之和,value 放a和b两数之和出现的次数。这组数据,当遍历到第一个-2 的时候,判断 下一个也是-2,那这组数据就pass了。遍历大A和大B数组,统计两个数组元素之和,和出现的次数,放到map中。

semirc9的博客 2435

代码随想录算法训练营第七 | 454.四数相加II383. 赎金15. 三数之和18. 四数之和

数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下标位置,因为要返回x 和 y的下标。所以set 也不能用。这时候就可以用到字典了。

懒羊羊在努力的博客 2308

随想录算法训练营Day7 | LeetCode 454.四数相加II383. 赎金15. 三数之和18. 四数之和

我们可以将四个数组分成两部分,A 和 B 为一组,C 和 D 为另外一组。对于 A 和 B,我们使用二重循环对它们进行遍历,得到所有 A[i]+B[j] 的值并存入哈希映射中。对于哈希映射中的每个键值对,每个键表示一种 A[i]+B[j],对应的值为 A[i]+B[j] 出现的次数。对于 C 和 D,我们同样使用二重循环对它们进行遍历。当遍历到 C[k]+D[l] 时,如果 −(C[k]+D[l]) 出现在哈希映射中,那么将 −(C[k]+D[l]) 对应的值累加进答案中。

weixin_66774683的博客 1742

代码随想录算法训练营Day7454. 四数相加II383. 赎金15. 三数之和18. 四数之和

是day7,依然是哈希表,上几道比较有难度的核心算法题练习。

weixin_43978140的博客 1703

代码随想录算法训练营第七|LeetCode 454.四数相加||383. 赎金15. 三数之和18. 四数之和

状态:联想昨的两数之和,不知道四个数的话怎么判断target-num,不会做这道题也要用map假设四个数组分别是ABCD前两个数组取出元素a+b 并统计出现的次数放到map里,遍历后两个数组c+d,查询0-(a+b)是否出现在map,出现的话即找到符合相加=0的四数元组。这样就解决了状态里我不会的那个点。至于为什么不是先遍历a,再遍历b+c+d,因为两个N^2的时间复杂度优于N+N^3。

Anastasia_sakura的博客 1830

算法训练营day07(哈希表02:四数相加,赎金,三数之和,四数之和,哈希表总结)

注意和三数之和的区别就是外面又套了一层for循环,另外target可能小于零,剪枝的时候要注意最小的nums[k]>target后面也可能符合题意,比如[-4,-1,0,0]target是-5,虽然-4>-5但是依然可以,所以nums[k]需要>=0。//用nums[k-1]而不是k+1,举例[-1,-1,2],用k+1把第二个-1就去掉了。//这里写的有点乱,kij是三个下标,ij就是两个指针,三元数组是nums[k]nums[i]nums[j]//相同的nums[k]和nums[i]继续找cd。

weixin_61931006的博客 2337

代码随想录算法训练营7|LeetCode454.四数相加||LeetCode383.赎金LeetCode15.三数之和LeetCode18.四数之和

代码随想录算法训练营7|LeetCode454.四数相加||LeetCode383.赎金LeetCode15.三数之和LeetCode18.四数之和

weixin_63948917的博客 1476

代码随想录算法训练营第七|Leetcode454 四数相加IILeetcode383 赎金Leetcode15 三数之和Leetcode18 四数之和

题目描述:给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i!输入:nums1 = [1,2], nums2 = [-2,-1], nums3 = [-1,2], nums4 = [0,2]输入:nums1 = [0], nums2 = [0], nums3 = [0], nums4 = [0]进行去重的话,将会pass{0,0,0}进入结果集,导致返回结果不完全。输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]

Demok123的博客 981

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

可以这样理解,将排序后的数组看成一级级的台阶,先去重是将指针移到了台阶的边缘,这时收缩后就可以上下台阶;思路: 需要ket和value,用unordered_map遍历一下即可,由于分四个数组,故不用考虑重复的问题;第七打卡,debug时思考很多,记录如上,另外有些方法(哈希表)和操作(剪枝)没写,后续有时间补全,加油!思路: key有限,用数组记录,最后出现负数即false,和 LeetCode242.有效的字母异位词 很像。思路:和 15. 三数之和 一样,采用双指针的方法,多加了一层循环;

qq_55232233的博客 1885

代码随想录算法训练营第七| 454.四数相加II383. 赎金15. 三数之和18. 四数之和

代码随想录算法训练营第七| 454.四数相加II383. 赎金15. 三数之和18. 四数之和

2301_81109252的博客 1034

代码随想录算法训练营Day7LeetCode454 四数相加IILeetCode383 赎金LeetCode15 三数之和LeetCode18 四数之和

这道题非常有意思,正常计算三数之和直接对两个数字使用哈希表就好了,但是这里的数组是有重复的,因此不方便用哈希表来去做,而是要使用双指针。这道题由于和前面的三数之和一样返回数字,因此继续使用双指针法,但是后面几个测试用例让我错了很多次,这里讲一讲我错误的几个地方:①a和三数之和的第一个数一样需要。这道题是计算四个数相加的元组的个数,相加可以想到使用哈希表,因为就相当于在一组数中找刚刚数的相反数,由于需要统计符合条件的个数,因此需要使用。,后面就变成了三数之和的问题;,有两种方式:第一种是对前三个数组构造。

weixin_51001256的博客 812

算法训练营Day7- 454.四数相加II383. 赎金15. 三数之和18. 四数之和

的题目有点上强度了,加油!

2401_87984806的博客 1443

代码随想录算法训练营第六 | LeetCode454.四数相加II383. 赎金15. 三数之和18. 四数之和

哈希表的map映射学习、set复习和与双指针结合应用的学习

m0_67729424的博客 1127

代码随想录算法训练营第七|454.四数相加II383. 赎金15. 三数之和18. 四数之和

题意:给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?满足要求的四元组集合为: [ [-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0, 2] ]否则返回 false。给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。

wunan233的博客 882

力扣(合并区间)

给定一组可能重叠或相邻的整数区间,合并所有重叠或端点相接的区间,返回不重叠的最小区间列表。例如输入 [[1,3],[2,6],[8,10],[15,18]],输出 [[1,6],[8,10],[15,18]]。核心是先按左端点升序排序,再单次线性扫描完成合并,避免暴力两两比较。

weixin_52811458的博客 295
上一篇: 代码随想录算法训练营第6天| leetcode ● 242.有效的字母异位词 ● 349. 两个数组的交集 ● 202. 快乐数● 1. 两数之和
下一篇: 代码随想录算法训练营第8天| leetcode 344反转字符串 541反转字符串 剑指Offer 05替换空格 151翻转字符串里的单词 剑指Offer58-II.左旋转字符串
樊城太守
博客等级 码龄5年 0粉丝 · 8原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值