Day10 代码随想录 刷题记录

总结:

共刷3题,总计用时5h25mins。

6.3开始进入旅游状态,休息了几天,零零散散敲了点代码,看了下整体的思路。后面应该要更加大强度,同时跟进相关基础知识的学习。

383. 赎金信

自己的想法:

跟字母异位词的思路很相似,不同的是其中一个和另一个还可以是包含的关系。可以通过设置数组,来验证在A中出现的值是否在B中也出现过。

设置一个长度为26的数组对应小写字母的下标,再根据A中出现的值将其录入,最终可以得到对应的小写字母出现的次数。再在遍历B的数组的过程中减去相应的值,如果最后数组的每个值没有为负数的,则说明resNote可以由magzine组成。

思路正确√解答正确√

第15题. 三数之和

自己的想法:

跟下标没关系,是不是可以直接用unordered_set的方式来求解。将循环遍历的两个轮换的值作为得到的初步的结果。

但是这个初步的结果对应的使用的值要如何保存,以及在求第三个数的时候,怎么保证第三个数不会跟1、2个数重复?(不同于最开始做的分别给了三个不同数组的题目,但是在这里需要考虑到的是同一个数组这样的情况)

正确的做法:哈希表 or 双指针

用哈希表的相关方法来做无法得到相关的结论。要考虑的边界与去重的部分太多了。

推荐用的是双指针的构造手法,构建的结果是从排序的数组中挑选三个数进行相加来判断。

双指针的思路:

得到的结果的三个值均不同,且得到的组别的结果不重复。

首先对数组进行排序相关的处理,即只需要考虑已经排完序的指针不会反复指到同一个地方,只需要对单个指针的前后移动“不重复”进行判断即可。

对首先定义的nums[i]的数组要进行去重的工作:nums[i] == nums[i - 1]。

对于right和left相关的定义是right是数组末尾对应的值,right是i + 1后面对应的值。

其次对于双指针所用到的left和right相关的数组,去重的时候应该考虑到如果nums[right] == nums[right  + 1]以及nums[left] == nums[left + 1],直接移动right和left的值,right++,left++。

continue语句的用法:

continue语句的作用是跳过本次循环体中剩下尚未执行的语句,立即进行下一次的循环条件判定,可以理解为只是中止(跳过)本次循环,接着开始下一次循环。

result定义的二元数组:

返回的值是一个二维动态数组。

在 C++ 中,vector<vector<int>> 是一个二维动态数组(嵌套的向量结构)。它本质上是一个向量(vector),其中每个元素又是一个存储整数的向量(vector<int>)。

注意的点:

1.如果经过排序后的数组不满足原题条件,采用的方法是直接跳出循环/return result。因为此时return的值就是仅经过了初始化的值。

2.自己在复原代码的时候写的思路有点问题,不能以去重为基础写while

 while(nums[left] == nums[left + 1] || nums[right] == nums[right + 1]){//去重要在第一轮判断之后进行

                left ++;

                right ++;//使用去重的判断

            }

否则只有在数组有重复值的时候才会进行移动的操作,本质上数组没有进行遍历和查找相关值的工作。

核心判断逻辑应为 经过排序后的数组的特定双指针中的某一个指针进行移动。

3.找到符合 == 0的答案时,才对其进行去重的操作。

4.在多层嵌套循环中,一定要注意临界条件。

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

                    left ++;//去重要在第一轮判断之后进行

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

虽然有宏观的while(left < right),但是在变化的过程中仍然无法绝对保证(left < right),所以在进行新的变化的时候要保证一致性。

第18题. 四数之和

自己的想法:

运用三数之和的想法,固定一个i值,再在循环的基础上也固定一个j值,再固定left值是i值后一位,right值是j值前一位。运用这个思路求解。

也是先对数组进行排序。然后采用三数之和的套路来求解。

但是要注意的是i和j不能同时移动。否则无法实现对于其遍历的操作。

正确的做法:

使用双重循环。整体思路还是一样的,首先先进行单层循环固定,去重之后再套用一层新的循环,新的循环的i值设为原有的+1形式。再同样使用去重。

后面所设定的left/right的形式同三重循环的操作一样。

注意:
1.在对j进行去重操作的时候,j的判断条件是j > i + 1,且j的判断条件是nums[j] == nums[j - 1]。

2.

                   if((long)nums[i] + nums[j] + nums[left] + nums[right] > target)

                            right --;

                   else if((long)nums[i] + nums[left] + nums[right] + nums[j] < target)

                            left ++;

因为可能出现越界溢出的情况,所以在相加的时候要加上(long)作为前缀的部分来使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值