day13: 第六章 二叉树part01 |二叉树的前序遍历,后序遍历,中序遍历,(递归。层序(广度)跟迭代遍历)
二叉树递归三部曲:
1. 确定递归函数的参数和返回值。
2. 确定终止条件
3.确定单层递归的逻辑
144.二叉树的前序遍历:中左右,递归:
class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<Integer>(); preorder(root, res); return res; } public void preorder(TreeNode root, List<Integer> res){ if(root == null){ return; } res.add(root.val); preorder(root.left, res); preorder(root.right, res); } }
迭代:
class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<>(); if(root == null) return res; Stack<TreeNode> stack = new Stack<>(); //栈里边先放右边,再放左边。 stack.push(root); while(!stack.isEmpty()){ TreeNode node = stack.pop(); res.add(node.val); if(node.right != null){ stack.push(node.right); } if(node.left != null){ stack.push(node.left); } } return res; } }
145.二叉树的后序遍历:左右中
class Solution { public List<Integer> postorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<>(); postorder(root, res); return res; } public void postorder(TreeNode root, List<Integer> res){ if(root == null) return; postorder(root.left, res); postorder(root.right,res); res.add(root.val); } }
迭代:翻转前序遍历
class Solution { public List<Integer> postorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<>(); if(root == null) return res; Stack<TreeNode> stack = new Stack<>(); //放进去翻转 stack.push(root); while(!stack.isEmpty()){ TreeNode node = stack.pop(); res.add(node.val); if(node.left != null){ stack.push(node.left); } if(node.right != null){ stack.push(node.right); } } Collections.reverse(res); return res; } }
94.二叉树的中序遍历:左中右
class Solution { public List<Integer> inorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<>(); inorder(root, res); return res; } public void inorder(TreeNode root, List<Integer> res){ if(root == null){ return; } inorder(root.left, res); res.add(root.val); inorder(root.right, res); } }
迭代:一路向左
class Solution { public List<Integer> inorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<>(); if(root == null) return res; Stack<TreeNode> stack = new Stack<>(); TreeNode cur = root; while(cur != null || !stack.isEmpty()){ //一路向左压栈,直到为空,因为左是空,出栈加入数字,check右孩子 //如果有右孩子就压栈,然后继续往左走,出栈check右孩子,继续循环 if(cur != null){ stack.push(cur); cur = cur.left; }else{ cur = stack.pop(); res.add(cur.val); cur = cur.right; } } return res; } }
102.二叉树的层序遍历 层序:
class Solution { public List<List<Integer>> levelOrder(TreeNode root) { //每次把一层的放进去,记录一个size. //二维数据 List <List<Integer>> list = new ArrayList<List<Integer>>(); if(root == null) return list; Queue<TreeNode> que = new LinkedList<>(); que.offer(root); while(!que.isEmpty()){ //二维数组中的其中一维 List<Integer> item = new ArrayList<>(); int size = que.size(); while(size > 0){ TreeNode temp = que.poll(); item.add(temp.val); if(temp.left != null){ que.offer(temp.left);} if(temp.right != null){que.offer(temp.right);} size--; } list.add(item); } return list; } }
一套代码打10个:
107.二叉树的层次遍历II
class Solution {
//102翻转一下 public List<List<Integer>> levelOrderBottom(TreeNode root) { List<List<Integer>> res = new ArrayList<>(); Queue<TreeNode> que = new LinkedList<>(); if(root == null) return res; que.offer(root); while( !que.isEmpty()){ List<Integer> temp = new ArrayList<>(); int size = que.size(); while(size > 0){ TreeNode node = que.poll(); temp.add(node.val); if(node.left != null){ que.offer(node.left); } if(node.right != null){ que.offer(node.right); } size--; } res.add(temp); } List<List<Integer>> nres = new ArrayList<>(); for(int i = res.size() - 1; i>= 0; i--){ nres.add(res.get(i)); } return nres; } }
199.二叉树的右视图
class Solution { public List<Integer> rightSideView(TreeNode root) { List<Integer> list = new ArrayList<>(); Queue<TreeNode> que = new LinkedList<>(); if(root == null) return list; que.offer(root); while(!que.isEmpty()){ //层序遍历模版只把最后一个加到结果里 int size = que.size(); for(int i = 0; i < size; i++){ TreeNode node = que.poll(); if(node.left != null){ que.offer(node.left); } if(node.right != null){ que.offer(node.right); } if( i == size - 1){ list.add(node.val); } } } return list; } }
637.二叉树的层平均值
class Solution { public List<Double> averageOfLevels(TreeNode root) { List<Double> list = new ArrayList<>(); Queue<TreeNode> que = new LinkedList<>(); if(root == null) return list; que.offer(root); while(!que.isEmpty()){ int levelSize = que.size(); double sum = 0.0; for(int i = 0; i < levelSize; i++){ TreeNode node = que.poll(); sum += node.val; if(node.left != null){ que.offer(node.left); } if(node.right != null){ que.offer(node.right); } } list.add(sum / levelSize); } return list; } }
429.N叉树的层序遍历
class Solution { public List<List<Integer>> levelOrder(Node root) { List<List<Integer>> list = new ArrayList<>(); Queue<Node> que = new LinkedList<>(); if(root == null) return list; que.offer(root); while(!que.isEmpty()){ int size = que.size(); List<Integer> temp = new ArrayList<>(); for(int i = 0; i < size; i++){ Node node = que.poll(); temp.add(node.val); //孩子节点的处理 List<Node> children = node.children; if(children == null || children.size() == 0 ){ continue; } for(Node n: children){ if(n != null){ que.offer(n); } } } list.add(temp); } return list; } }
515.在每个树行中找最大值
class Solution { public List<Integer> largestValues(TreeNode root) { List<Integer> list = new ArrayList<>(); Queue<TreeNode> que = new LinkedList<>(); if(root == null) return list; que.offer(root); while(!que.isEmpty()){ int size = que.size(); //用max记录最大值 //max赋最小值写法 int max = Integer.MIN_VALUE;; for(int i = 0; i < size; i++){ TreeNode node = que.poll(); max = Math.max(max, node.val); if(node.left != null){ que.offer(node.left); } if(node.right != null){ que.offer(node.right); } } list.add(max); } return list; } }
116.填充每个节点的下一个右侧节点指针代码参考:【leetcode-树篇 116题 填充每个节点的下一个右侧节点指针】 https://www.bilibili.com/video/BV1B84y1L7U9/?share_source=copy_web&vd_source=63b55f16632bf78a8dcad7616b01e190
class Solution { public Node connect(Node root) { if(root == null) return null; Queue<Node> que = new LinkedList<>(); que.offer(root); while(!que.isEmpty()){ int size = que.size(); for(int i = 0; i < size; i++){ Node temp = que.poll(); if(i == size - 1){ temp.next = null; }else{ temp.next = que.peek(); } if(temp.left != null){ que.offer(temp.left); } if(temp.right != null){ que.offer(temp.right); } } } return root; } }
117.填充每个节点的下一个右侧节点指针II:跟116同一个代码不同改。
104.二叉树的最大深度=》 while 循环一次+1;
class Solution { public int maxDepth(TreeNode root) { if(root == null) return 0; Queue<TreeNode> que = new LinkedList<>(); int depth = 0; que.offer(root); while(!que.isEmpty()){ int size = que.size(); for(int i = 0; i < size; i++){ TreeNode temp = que.poll(); if(temp.left != null){ que.offer(temp.left); } if(temp.right != null){ que.offer(temp.right); } } //while 循环一次+1 depth++; } return depth; } }
111.二叉树的最小深度:如果左右都为空就返回。
class Solution { public int minDepth(TreeNode root) { if(root == null) return 0; Queue<TreeNode> que = new LinkedList<>(); int depth = 0; que.offer(root); while(!que.isEmpty()){ //如果左右都为空就返回。 int size = que.size(); depth++; for(int i = 0; i < size; i++){ TreeNode temp = que.poll(); if(temp.left == null && temp.right == null){ return depth; } if(temp.left != null){ que.offer(temp.left); } if(temp.right != null){ que.offer(temp.right); } } } return depth; } }