持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情
前言
算法的重要性不言而喻!区分度高!
现在学习的门槛低了,只有能上网每个人都可以学编程!培训班6个月就可以培养出来能干活的人,你怎么从这些人中脱颖而出?没错!就是学算法,学一些底层和基础的东西。
说的功利点是为了竞争,卷死对手。真心话说就是能提高自己的基础能力,为技术可持续发展做好充分的准备!!!
提前入门学习书籍:CPrimerPlus、大话数据结构
刷题网站
我是按照代码随想录提供的刷题顺序进行刷题的,大家也可以去刷leetcode最热200道,都可以
刷题嘛,最重要的就是坚持了!!!
画图软件
OneNote
这个要经常用,遇见不懂的流程的话就拿它画一画!
笔记软件
Typoral
题目
解析
双指针
刚写过三数之和,又来四数之和?这能难住我吗?哈哈哈!
其实四数之和跟三数之后一个思路,都是使用双指针法,所以就是在三数之和的基础上在套一个for循环就能实现四数之和
- 使用四个指针(a<b<c<d)。最小的a和b在左边,c=b+1,d=数组的大小-1 只需要移动后两个指针然后包夹求解即可。
- 保存使得nums[a]+nums[b]+nums[c]+nums[d]==target的解。
- target偏大d向左移动,偏小时c右移。如果c和d相遇,就说明以a和b为最小值已经全部求完了。所以需要更换值了,我们需要先更换b的值,所以我们b++,进入下一轮循环。当b的循环结束了,a++,进入a的循环
我们是不是还忘了一件事?没错!我们还需要先对数组元素进行排序才能用这个方法
剪纸操作(去除重复解):
我们要确保移动指针后,对应的数字要发生改变才行哦。
public List<List<Integer>> fourSum(int[] nums, int target) {
//存放结果集
List<List<Integer>> result = new ArrayList<>();
//使用双指针必须排序
Arrays.sort(nums);
//控制第一层循环
for (int i = 0; i < nums.length; i++) {
// nums[i] > target 直接返回, 返回为空,因为第一个数都大于目标值的话后面相加不可能等于target
if (nums[i] > 0 && nums[i] > target) {
return result;
}
//对第一个指针进行一个去重的操作
// 这里的i>0是为了预防数组越界
if (i > 0 && nums[i - 1] == nums[i]) {
continue;
}
//控制第二层循环
for (int j = i + 1; j < nums.length; j++) {
//对第二个指针进行去重的操作
if (j > i + 1 && nums[j - 1] == nums[j]) {
continue;
}
//第三个指针的位置
int left = j + 1;
//第四个指针的位置
int right = nums.length - 1;
//控制第三个和第四个指针碰头,另外两个指针不动
while (right > left) {
//计算是否等于目标值
long sum = (long) nums[i] + nums[j] + nums[left] + nums[right];
//如果target小于sum,第四个指针左移,因为第三个指针已经是数组中倒数第三小的了
if (sum > target) {
right--;
//如果target大于sum,移动第三个指针,因为第四个指针已经是数组中最大值了
} else if (sum < target) {
left++;
//如果target等于sum,那么返回数组中的数对应的索引下标,并把它们当成集合的形式传到结果集中
} else {
result.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
//找到结果之后还要对三、四指针进行去重操作
while (right > left && nums[right] == nums[right - 1]) right--;
while (right > left && nums[left] == nums[left + 1]) left++;
//如果不重复那就三、四指针正常移动
left++;
right--;
}
}
}
}
//返回结果集
return result;
}
代码中也有详细的解释,实在不明白的话可以dubug一下