前言
算法的重要性不言而喻!区分度高!
现在学习的门槛低了,只有能上网每个人都可以学编程!培训班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一下