128 lines
4.5 KiB
Markdown
Executable File
128 lines
4.5 KiB
Markdown
Executable File
- 二叉树的遍历 #算法
|
||
- 使用递归
|
||
- 注意终止条件,将root和集合传入函数
|
||
- 非递归
|
||
- 使用栈
|
||
- 前序遍历 root->left->right
|
||
- [144. 二叉树的前序遍历 - 力扣(LeetCode)](https://leetcode.cn/problems/binary-tree-preorder-traversal/)
|
||
- 中序遍历 left->root->right
|
||
- [94. 二叉树的中序遍历 - 力扣(LeetCode)](https://leetcode.cn/problems/binary-tree-inorder-traversal/)
|
||
- 后序遍历 left->right->root
|
||
- [145. 二叉树的后序遍历 - 力扣(LeetCode)](https://leetcode.cn/problems/binary-tree-postorder-traversal/)
|
||
- 排序算法 #算法
|
||
- [912. 排序数组 - 力扣(LeetCode)](https://leetcode.cn/problems/sort-an-array/description/)
|
||
- 冒泡排序
|
||
- 快速排序
|
||
- 选择排序
|
||
- 三数之和 #算法
|
||
- [15. 三数之和 - 力扣(LeetCode)](https://leetcode.cn/problems/3sum/)
|
||
collapsed:: true
|
||
- ```java
|
||
//给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j !=
|
||
//k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请
|
||
//
|
||
// 你返回所有和为 0 且不重复的三元组。
|
||
//
|
||
// 注意:答案中不可以包含重复的三元组。
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
// 示例 1:
|
||
//
|
||
//
|
||
//输入:nums = [-1,0,1,2,-1,-4]
|
||
//输出:[[-1,-1,2],[-1,0,1]]
|
||
//解释:
|
||
//nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
|
||
//nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
|
||
//nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
|
||
//不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
|
||
//注意,输出的顺序和三元组的顺序并不重要。
|
||
//
|
||
//
|
||
// 示例 2:
|
||
//
|
||
//
|
||
//输入:nums = [0,1,1]
|
||
//输出:[]
|
||
//解释:唯一可能的三元组和不为 0 。
|
||
//
|
||
//
|
||
// 示例 3:
|
||
//
|
||
//
|
||
//输入:nums = [0,0,0]
|
||
//输出:[[0,0,0]]
|
||
//解释:唯一可能的三元组和为 0 。
|
||
//
|
||
//
|
||
//
|
||
//
|
||
// 提示:
|
||
//
|
||
//
|
||
// 3 <= nums.length <= 3000
|
||
// -10⁵ <= nums[i] <= 10⁵
|
||
//
|
||
//
|
||
// Related Topics 数组 双指针 排序 👍 6404 👎 0
|
||
|
||
|
||
import java.sql.Array;
|
||
import java.util.ArrayList;
|
||
import java.util.Arrays;
|
||
|
||
//leetcode submit region begin(Prohibit modification and deletion)
|
||
class Solution {
|
||
public List<List<Integer>> threeSum(int[] nums) {
|
||
List<List<Integer>> result = new ArrayList<List<Integer>>();
|
||
int n = nums.length;
|
||
Arrays.sort(nums);
|
||
for (int first = 0; first < n -2; ++first) {
|
||
// 如果a的值与上一轮一样就跳过
|
||
if(first != 0 && nums[first] == nums[first - 1]) {
|
||
continue;
|
||
}
|
||
if (nums[first] + nums[first + 1] + nums[first + 2] > 0) {
|
||
break;
|
||
}
|
||
if (nums[first] + nums[n-1] +nums[n-2] < 0) {
|
||
continue;
|
||
}
|
||
//c为nums末端值
|
||
int third = n -1;
|
||
int target = -nums[first];
|
||
for (int second = first + 1; second < n -1; ++second) {
|
||
// 如果b的值和上一轮相同跳过
|
||
if(second > first + 1 && nums[second] == nums[second - 1]) {
|
||
continue;
|
||
}
|
||
// 固定a和b,移动c且保证c>a
|
||
while(second < third && nums[third] + nums[second] > target) {
|
||
--third;
|
||
}
|
||
// 如果b和c重合,终止b的循环
|
||
if(second == third) {
|
||
break;
|
||
}
|
||
if (nums[third] + nums[second] == target){
|
||
result.add(Arrays.asList(nums[first], nums[second], nums[third]));
|
||
}
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
}
|
||
//leetcode submit region end(Prohibit modification and deletion)
|
||
|
||
```
|
||
- 排序+双指针
|
||
- 注意值的变化,两个for循环都是使用++first及++second
|
||
- 第二个值从first+1开始变化
|
||
- 第三个值初始为n-1使用while来进行自减,即--third,需要判断三个值是否大于0且second要小于third
|
||
- 优化
|
||
- 因为已经排序,可以判断连续的三个是否大于0,大于0可以不用再找了
|
||
- 可以判断a与末尾的两个数是否小于0,小于0可以跳过此轮b循环
|
||
- 注意a的值要取n-2,b取n-1,否则会发生下标越界 |