leetcode-二叉树
二叉树遍历用递归的方式比较简单,但是迭代还是稍微有点绕,记录一下二叉树迭代遍历的统一框架,以防忘记:
主要的思路依旧是栈解决,但是为了当前栈顶元素是否需要被加入到result list中,巧妙地在需要被加入到result list中的元素之前加上一个null以示区分。
102. 二叉树的层序遍历 - 力扣(LeetCode)
代码如下:
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { public List<Integer> inorderTraversal(TreeNode root) { List<Integer> res = new LinkedList<>(); Stack<TreeNode> stack = new Stack<>(); if(root == null) return res; stack.push(root); while(stack.size() > 0){ TreeNode cur = stack.pop(); if(cur != null){ //先push右节点,因为stack具有FIFO的特性 if(cur.right != null) stack.push(cur.right); //push当前节点,并且用null标记 stack.push(cur); stack.push(null); //push左节点 if(cur.left != null) stack.push(cur.left); } //如果当前栈顶元素为null,则说明需要加入到list当中 else{ res.add(stack.pop().val); } } return res; } }
先序和后序只需要调整左中右三个节点的入栈顺序,非常方便。
226. 翻转二叉树 - 力扣(LeetCode)
可以通过先序遍历或者后序遍历,一边遍历一边反转。(中序遍历不行,会导致多次反转)
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { //先序遍历反转 public TreeNode invertTree(TreeNode root) { dfs(root); return root; } public void dfs(TreeNode node){ if(node == null) return; //反转 TreeNode temp = node.left; node.left = node.right; node.right = temp; dfs(node.left); dfs(node.right); } }
101. 对称二叉树 - 力扣(LeetCode)
判断二叉树是否对成,可以采用迭代法或者递归法,本质就是一个一个节点比较:
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { //迭代法,简单来说就是左右子树一个一个节点进行比较,可以用队列或者栈来存储每个子树的节点 public boolean isSymmetric(TreeNode root) { Stack<TreeNode> stackLeft = new Stack<>(); Stack<TreeNode> stackRight = new Stack<>(); stackLeft.push(root.left); stackRight.push(root.right); while(!stackLeft.isEmpty() && !stackRight.isEmpty()){ TreeNode left = stackLeft.pop(); TreeNode right = stackRight.pop(); if(left == null && right == null) continue; if(left == null || right == null) return false; if(left.val != right.val) return false; //按照比较顺序加入即可 stackLeft.push(left.left); stackLeft.push(left.right); stackRight.push(right.right); stackRight.push(right.left); } if(!stackLeft.isEmpty() || !stackRight.isEmpty()) return false; return true; } } //递归法 class Solution { public boolean isSymmetric(TreeNode root) { return compare(root.left, root.right); } public boolean compare(TreeNode left, TreeNode right){ //四种情况 //两方均为空,返回true if(left == null && right == null) return true; //一方为空,返回false if(left == null || right == null) return false; //两方均不为空,但值不相等,返回false if(left.val != right.val) return false; //以上条件均不满足,则说明left.val == right.val,此时要进一步进行判断 boolean compareInside = compare(left.right, right.left); boolean compareOutside = compare(left.left, right.right); return compareInside && compareOutside; } }