总结:
共刷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)作为前缀的部分来使用。
1700

被折叠的 条评论
为什么被折叠?



