递归大致思路
- 确定递归函数的参数和返回值
- 确定终止条件
- 确定单层递归的逻辑
先序 递归遍历
中序 递归遍历
后序 递归遍历
先序 迭代遍历
class Solution {
List<Integer> ans = new ArrayList<Integer>();
public List<Integer> preorderTraversal(TreeNode root) {
preOrder(root);
return ans;
}
public void preOrder(TreeNode node){
if (node == null) return ;
ans.add(node.val);
preOrder(node.left);
preOrder(node.right);
}
}
中序 迭代遍历
class Solution {
List<Integer> ans = new ArrayList<Integer>();
public List<Integer> preorderTraversal(TreeNode root) {
preOrder(root);
return ans;
}
public void preOrder(TreeNode node){
if (node == null) return ;
preOrder(node.left);
ans.add(node.val);
preOrder(node.right);
}
}
后序 迭代遍历
class Solution {
List<Integer> ans = new ArrayList<Integer>();
public List<Integer> preorderTraversal(TreeNode root) {
preOrder(root);
return ans;
}
public void preOrder(TreeNode node){
if (node == null) return ;
preOrder(node.left);
preOrder(node.right);
ans.add(node.val);
}
}
层序遍历
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
if (root == null)
return new ArrayList<>();
List<List<Integer>> res = new ArrayList<>();
// 使用队列来完成层序遍历
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root);
while(!queue.isEmpty()){
int num = queue.size();
List<Integer> list = new ArrayList<>();
while(num>0){
// 出队列,将它下一层的子树添加到队列中
TreeNode node = queue.poll();
list.add(node.val);
if(node.left!=null)
queue.add(node.left);
if(node.right!=null)
queue.add(node.right);
// 通过这个计数来区别不同层节点
num--;
}
// 遍历完二叉树的一层,将结果添加到结果集
res.add(list);
}
return res;
}
}
回溯算法
// 可以在主函数之外,作为类的全局变量
void backtrace(全局){
if(终止条件){
// 收集结果
return;
}
for(集合元素){
// 处理节点
// 递归函数
// 撤销操作
}
return;
}
什么时候使用 used 数组,什么时候使用 begin 变量
- 排列问题,讲究顺序(即 [2, 2, 3] 与 [2, 3, 2] 视为不同列表时),需要记录哪些数字已经使用过,此时用 used 数组;
- 组合问题,不讲究顺序(即 [2, 2, 3] 与 [2, 3, 2] 视为相同列表时),需要按照某种顺序搜索,此时使用 begin 变量。
动态规划
- 确定dp数组下标的意义
- 确定递推关系
- 确定数组初始状态
- 确定递推顺序
- 举例推导dp数组
以下是使用二维dp数组解决不同路径的代码
class Solution {
public int uniquePaths(int m, int n) {
int[][] dp = new int[m][n];
for (int i=0;i<m;i++){
dp[i][0] = 1;
}
for (int i=0;i<n;i++){
dp[0][i] = 1;
}
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
dp[i][j] = dp[i-1][j]+dp[i][j-1];
}
}
return dp[m-1][n-1];
}
}
优化存储的动态规划
层序遍历
层序遍历