前言
算法的重要性不言而喻!区分度高!
现在学习的门槛低了,只有能上网每个人都可以学编程!培训班6个月就可以培养出来能干活的人,你怎么从这些人中脱颖而出?没错!就是学算法,学一些底层和基础的东西。
说的功利点是为了竞争,卷死对手。真心话说就是能提高自己的基础能力,为技术可持续发展做好充分的准备!!!
提前入门学习书籍:CPrimerPlus、大话数据结构
刷题网站
我是按照代码随想录提供的刷题顺序进行刷题的,大家也可以去刷leetcode最热200道,都可以
刷题嘛,最重要的就是坚持了!!!
画图软件
OneNote
这个要经常用,遇见不懂的流程的话就拿它画一画!
笔记软件
Typoral
题目
解析
暴力思路
三层for循环 都可以想到的方法,但是它行不行呢?
public class TheSumOfThreeNumbers { public static void main(String[] args) { int[] nums = {-1, 0, 1, 2, -1, -4}; ArrayList<List<Integer>> arrayList = new ArrayList<>(); for (int i = 0; i < nums.length; i++) { for (int j = i + 1; j < nums.length; j++) { for (int k = j + 1; k < nums.length; k++) { int sum = nums[i] + nums[j] + nums[k]; if (sum == 0){ arrayList.add(Arrays.asList(nums[i],nums[j],nums[k])); } } } } arrayList.forEach(x -> System.out.println(x)); } }
不太行,因为[-1,0,1],[0,1,-1]]算是重复的啦,换位置也不行
双指针
这题的确不好想,看题解中的例子是使用指针的方法:
- 首先对数组排序
- 定义二个指针
- 循环for目的是遍历数组,i从下标0开始
- 第一个指针left从i+1开始,代表第二个数
- 第二个指针right在数组尾部,代表第三个数
相当于 a = nums[i],b = nums[left],c = nums[right]。
接下来如何移动left 和right呢?
想起我们刚开始对数组做的排序了吗?如果nums[i] + nums[left] + nums[right] > 0 就说明 此时三数之和大了所以right下标就应该向左移动,这样才能让三数之和小一些。
nums[i] + nums[left] + nums[right] < 0 说明三数之和小了,left就向右移动,才能让三数之和大一些,直到left与right相遇为止。
时间复杂度:O(n^2)。
public static List<List<Integer>> threeSum(int[] nums) { ArrayList<List<Integer>> result = new ArrayList<>();//存放结果集,格式为[[],[],[]....] Arrays.sort(nums); //对目标数据进行排序 if (nums == null || nums.length < 3) { return result; } for (int i = 0; i < nums.length; i++) { if (nums[i] > 0) { return result; //临界条件的一些判断,如果排序后的第一个数都大于0那么三数之后不可能为0 } /** * 加上i > 0是因为第一个数没和前一个数比较,会出现数组越界 * 为i-1是因为,i是增加的,它要和后面的数比较看是否相等 */ if (i > 0 && nums[i] == nums[i - 1]) { // continue; //这里是对i的去重 } int left = i + 1; //左指针 int right = nums.length - 1; //右指针 while (right > left) { int sum = nums[i] + nums[left] + nums[right]; if (sum > 0) { right--; //和大于0,说明加的太大了,只能让right左移 } else if (sum < 0) { left++; //和小于0,说明加的太小了,只能让left右移 } else { result.add(Arrays.asList(nums[i], nums[left], nums[right]));//等于0,加入结果集 while (right > left && nums[left] == nums[left + 1]) left++;//对右指针去重 while (right > left && nums[right] == nums[right - 1]) right--;//对左指针去重 right--;//往左移动 left++;//往右移动 } } } return result; }
代码中也有详细的解释,实在不明白的话可以dubug一下