数据结构之树(其二)
//搜索一条边 if (函数(root.left)) return...; if (函数(root.right)) return...; //搜索整棵树 left = 函数(root.left); right = 函数(root.right); left与right逻辑处理
迭代用队列,栈也可以。戳这里
class Solution { public boolean isSymmetric(TreeNode root) { if (root == null) return true; return mirror(root.left, root.right); } public boolean mirror(TreeNode Nodeleft, TreeNode Noderight) { if (Nodeleft == null && Noderight == null) return true; if (Nodeleft == null && Noderight != null) return false; if (Nodeleft != null && Noderight == null) return false; if (Nodeleft.val != Noderight.val) return false; return mirror(Nodeleft.right, Noderight.left) && mirror(Nodeleft.left, Noderight.right); } }
class Solution { public boolean isSymmetric(TreeNode root) { if (root == null) return true; Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root.left); queue.offer(root.right); while (!queue.isEmpty()) { TreeNode Nodeleft = queue.poll(); TreeNode Noderight = queue.poll(); if (Nodeleft == null && Noderight == null) continue; if (Nodeleft == null || Noderight == null) return false; if (Nodeleft.val != Noderight.val) return false; queue.offer(Nodeleft.left); queue.offer(Noderight.right); queue.offer(Nodeleft.right); queue.offer(Noderight.left); } return true; } }
递归就想成每一个节点都是1,从上一顺加下来。迭代就是层序遍历取层数。
class Solution { public int maxDepth(TreeNode root) { if (root == null) return 0; return 1 + Math.max(maxDepth(root.left), maxDepth(root.right)); } }
只有左右子节点都为空才行,只用一边为空的话还要从另一边继续向下。
class Solution { public int minDepth(TreeNode root) { if (root == null) return 0; if (root.left == null && root.right != null) return 1 + minDepth(root.right); if (root.right == null && root.left != null) return 1 + minDepth(root.left); return 1 + Math.min(minDepth(root.right), minDepth(root.left)); } }
class Solution { public int minDepth(TreeNode root) { if (root == null) return 0; Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); int deep = 0; while (!queue.isEmpty()) { int len = queue.size(); deep++; for (int i = 0; i < len; i++) { TreeNode temp = queue.poll(); if (temp.right == null && temp.left == null) return deep; if (temp.right != null) queue.offer(temp.right); if (temp.left != null) queue.offer(temp.left); } } return deep; } }
迭代依然是用层序遍历
class Solution { public int countNodes(TreeNode root) { if (root == null) return 0; return 1 + countNodes(root.left) + countNodes(root.right); } }
递归真的很像树。
class Solution { public boolean isBalanced(TreeNode root) { return getDepth(root) == -1 ? false : true; } public int getDepth(TreeNode root) { if (root == null) return 0; int leftDepth = getDepth(root.left); if (leftDepth == -1) return -1; int rightDepth = getDepth(root.right); if (rightDepth == -1) return -1; return Math.abs(leftDepth - rightDepth) <= 1 ? 1 + Math.max(leftDepth, rightDepth) : -1; } }
这就是套路啊,就是一个前序遍历。
class Solution { private int ans; public int sumOfLeftLeaves(TreeNode root) { sumLeft(root); return ans; } public void sumLeft(TreeNode root) { if (root == null) return; if (root.left != null && root.left.left == null && root.left.right == null) { ans += root.left.val; } sumLeft(root.left); sumLeft(root.right); } }
先右后左,这样最后一个出列的就是左下角了。也可以用层序遍历一层一层地找。
class Solution { public int findBottomLeftValue(TreeNode root) { Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); while (!queue.isEmpty()) { root = queue.poll(); if (root.right != null) queue.offer(root.right); if (root.left != null) queue.offer(root.left); } return root.val; } }
class Solution { public boolean hasPathSum(TreeNode root, int sum) { if (root == null) return false; if (root.right == null && root.left == null && sum == root.val) return true; return hasPathSum(root.left, sum-root.val) || hasPathSum(root.right, sum-root.val); } }
试了一下,这里用哈希表索引比循环遍历快了3倍。难点是后序和中序的左右子树的头和尾指针的变换。
class Solution { private Map<Integer, Integer> hashmap = new HashMap<>(); private int[] pos; public TreeNode buildTree(int[] inorder, int[] postorder) { for (int i = 0; i < inorder.length; i++) { hashmap.put(inorder[i], i); } pos = postorder; return build(0, inorder.length-1, 0, inorder.length-1); } public TreeNode build(int is, int ie, int ps, int pe) { if (is > ie || ps > pe) return null; int mid = hashmap.get(pos[pe]); TreeNode node = new TreeNode(pos[pe]); node.left = build(is, mid-1, ps, mid-1-is+ps); node.right = build(mid+1, pe+is-ps, mid-is+ps, pe-1); return node; } }
class Solution { private int[] pre; private Map<Integer, Integer> hashmap = new HashMap<>(); public TreeNode buildTree(int[] preorder, int[] inorder) { for (int i = 0; i < inorder.length; i++) { hashmap.put(inorder[i],i); } pre = preorder; return build(0, preorder.length-1, 0, inorder.length-1); } public TreeNode build(int ps, int pe, int is, int ie) { if (ps > pe || is > ie) return null; int mid = hashmap.get(pre[ps]); TreeNode node = new TreeNode(pre[ps]); node.left = build(ps+1,ps+mid-is,is,mid-1); node.right = build(ps+mid-is+1,pe,mid+1,ie); return node; } }
和上面一个思路,相当于切割左右子树
class Solution { public TreeNode constructMaximumBinaryTree(int[] nums) { return build(nums, 0, nums.length-1); } public TreeNode build(int[] nums, int l, int r) { if (l > r) return null; int index = l; int max = nums[index]; for (int i = l; i <= r; i++) { if (max < nums[i]) { index = i; max = nums[i]; } } TreeNode node = new TreeNode(nums[index]); node.left = build(nums, l, index-1); node.right = build(nums, index+1, r); return node; } }
又是前序遍历,t1为空时连接t2,t2为空是连接t1,体会一下。
class Solution { public TreeNode mergeTrees(TreeNode t1, TreeNode t2) { if (t1 == null) return t2; if (t2 == null) return t1; TreeNode node = new TreeNode(t1.val + t2.val); node.left = mergeTrees(t1.left, t2.left); node.right = mergeTrees(t1.right, t2.right); return node; } }

浙公网安备 33010602011771号