赞
踩
示例:
给定二叉树[3,9,20,null,null,15,7],返回它的最大深度3。
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
}
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
示例:
输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]
Map<Integer, Integer> inMap = new HashMap(); public TreeNode buildTree(int[] preorder, int[] inorder) { int preLength = preorder.length; int inLength = inorder.length; for (int j = 0; j < inLength; j++) { inMap.put(inorder[j], j); } return buildTreeNode(preorder, 0, preLength - 1, inorder, 0, inLength - 1); } private TreeNode buildTreeNode(int[] preorder, int preLeft, int preRight, int[] inorder, int inLeft, int inRight) { if (preLeft > preRight) { return null; } TreeNode head = new TreeNode(preorder[preLeft]); int inOrderIndex = inMap.get(preorder[preLeft]); int leftSize = inOrderIndex - inLeft; head.left = buildTreeNode(preorder, preLeft + 1, preLeft + leftSize, inorder, inLeft, inLeft + leftSize - 1); head.right = buildTreeNode(preorder, preLeft + leftSize + 1, preRight, inorder, inOrderIndex + 1, inRight); return head; }
例如,给出中序遍历 inorder = [9,3,15,20,7] 后序遍历postorder=[9,15,7,20,3] 返回如下的二叉树
private Map<Integer, Integer> inorderMap = new HashMap<>(); public TreeNode buildTree(int[] inorder, int[] postorder) { int length = inorder.length; for (int i = 0; i < length; i++) { inorderMap.put(inorder[i], i); } return buildTree(inorder, postorder, 0, length - 1, 0, length - 1); } public TreeNode buildTree(int[] inorder, int[] postorder, int inorderLeft, int inorderRight, int postorderLeft, int postorderRight) { if (inorderLeft > inorderRight || postorderLeft > postorderRight) { return null; } TreeNode head = new TreeNode(postorder[postorderRight]); int inorderHeadIndex = inorderMap.get(postorder[postorderRight]); int leftCount = inorderHeadIndex - inorderLeft; head.left = buildTree(inorder, postorder, inorderLeft, inorderLeft + leftCount - 1, postorderLeft, postorderLeft + leftCount - 1); head.right = buildTree(inorder, postorder, inorderHeadIndex + 1, inorderRight, postorderLeft + leftCount, postorderRight - 1); return head; }
示例:
输入:
输出:
public TreeNode invertTree(TreeNode root) {
if (root == null) {
return null;
}
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
invertTree(root.left);
invertTree(root.right);
return root;
}
示例:
输入Tree1:
输入Tree2:
输出:
合并后的树:
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if (root1 == null && root2 == null) {
return null;
}
int value1 = root1 == null ? 0 : root1.val;
int value2 = root2 == null ? 0 : root2.val;
TreeNode treeNode = new TreeNode(value1 + value2);
treeNode.left = mergeTrees(root1 == null ? null : root1.left, root2 == null ? null : root2.left);
treeNode.right = mergeTrees(root1 == null ? null : root1.right, root2 == null ? null : root2.right);
return treeNode;
}
示例:
给定二叉树
返回3,它的长度是路径[4,2,1,3]或者[5,2,1,3]
int maxLength = Integer.MIN_VALUE;
public int diameterOfBinaryTree(TreeNode root) {
calLength(root);
return maxLength;
}
private int calLength(TreeNode node) {
if (node == null) {
return 0;
}
int left = calLength(node.left);
int right = calLength(node.right);
maxLength = Math.max(left + right, maxLength);
return Math.max(left, right) + 1;
}
示例:
输入:root = [3,9,20,null,null,15,7]
输出:true
方法一:自顶向下的递归
public boolean isBalanced(TreeNode root) { if (root == null) { return true; } if (Math.abs(getDepth(root.left) - getDepth(root.right)) > 1) { return false; } return isBalanced(root.left) && isBalanced(root.right); } public int getDepth(TreeNode root) { if (root == null) { return 0; } return Math.max(getDepth(root.left), getDepth(root.right)) + 1; }
方法二:自底向上的递归
public boolean isBalanced(TreeNode root) { return height(root) >= 0; } public int height(TreeNode root) { if (root == null) { return 0; } int leftHeight = height(root.left); int rightHeight = height(root.right); if (leftHeight == -1 || rightHeight == -1 || Math.abs(leftHeight - rightHeight) > 1) { return -1; } else { return Math.max(leftHeight, rightHeight) + 1; } }
(此题关键点在于某个节点的左节点或右节点为空的情况)
示例:
输入:root = [3,9,20,null,null,15,7]
输出:2
public int minDepth(TreeNode root) {
if (root == null) {
return 0;
}
int left = minDepth(root.left);
int right = minDepth(root.right);
if (left == 0 || right == 0) {
return Math.max(left, right) + 1;
}
return Math.min(left, right) + 1;
}
示例:
输入:root = [3,4,5,1,2], subRoot = [4,1,2]
输出:true
public boolean isSubtree(TreeNode s, TreeNode t) { return dfs(s, t); } public boolean dfs(TreeNode s, TreeNode t) { if (s == null) { return false; } return check(s, t) || dfs(s.left, t) || dfs(s.right, t); } public boolean check(TreeNode s, TreeNode t) { if (s == null && t == null) { return true; } if (s == null || t == null || s.val != t.val) { return false; } return check(s.left, t.left) && check(s.right, t.right); }
若不限定子树包括 tree 的某个节点的所有后代节点,如下示例也满足的话:
输入:root = [3,4,5,1,2,null,null,null,null,0], subRoot = [4,1,2]
输出:true
private static TreeNode originSubTree; public static boolean isSubTree(TreeNode treeNode1, TreeNode treeNode2) { if (treeNode1 == null || treeNode2 == null) { return false; } originSubTree = treeNode2; return validTree1(treeNode1, treeNode1, treeNode2); } private static boolean validTree1(TreeNode mainTree, TreeNode curMainTree, TreeNode subTree) { if (subTree == null) { return true; } if (curMainTree == null) { return false; } if (curMainTree.val == subTree.val) { return validTree1(mainTree, curMainTree.left, subTree.left) && validTree1(mainTree, curMainTree.right, subTree.right); } return validTree1(mainTree.left, mainTree.left, originSubTree) || validTree1(mainTree.right, mainTree.right, originSubTree); }
示例:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出: true
方法1:递归
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) {
return false;
}
if (root.left == null && root.right == null) {
return targetSum == root.val;
}
return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
}
方法2:广度优先搜索
public boolean hasPathSum(TreeNode root, int sum) { if (root == null) { return false; } Queue<TreeNode> queNode = new LinkedList<TreeNode>(); Queue<Integer> queVal = new LinkedList<Integer>(); queNode.offer(root); queVal.offer(root.val); while (!queNode.isEmpty()) { TreeNode now = queNode.poll(); int temp = queVal.poll(); if (now.left == null && now.right == null) { if (temp == sum) { return true; } continue; } if (now.left != null) { queNode.offer(now.left); queVal.offer(now.left.val + temp); } if (now.right != null) { queNode.offer(now.right); queVal.offer(now.right.val + temp); } } return false; }
示例:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2], [5,8,4,5]]
List<List<Integer>> resultList = new ArrayList<>(); List<Integer> tempList = new ArrayList<>(); public List<List<Integer>> pathSum(TreeNode root, int targetSum) { dealTree(root, targetSum); return resultList; } private void dealTree(TreeNode root, int targetSum) { if (root == null) { return; } targetSum = targetSum - root.val; tempList.add(root.val); if (root.left == null && root.right == null && targetSum == 0) { resultList.add(new ArrayList<>(tempList)); } dealTree(root.left, targetSum); dealTree(root.right, targetSum); tempList.remove(tempList.size() - 1); }
示例:
输入:root = [1,2,3, null,5]
输出:[“1->2->5”,“1->3”]
public List<String> binaryTreePaths(TreeNode root) { List<String> result = new ArrayList<>(); constructPaths(root, result, ""); return result; } private void constructPaths(TreeNode root, List<String> result, String str) { if (root != null) { StringBuffer sb = new StringBuffer(str); sb.append(root.val); if (root.left == null && root.right == null) { result.add(sb.toString()); } else { sb.append("->"); constructPaths(root.left, result, sb.toString()); constructPaths(root.right, result, sb.toString()); } } }
示例:
输入:root = [1,2,5,3,4,null,6]
输出:[1,null,2,null,3,null,4,null,5,null,6]
public void flatten(TreeNode root) { TreeNode curr = root; while (curr != null) { if (curr.left != null) { TreeNode next = curr.left; TreeNode predecessor = next; while (predecessor.right != null) { predecessor = predecessor.right; } predecessor.right = curr.right; curr.left = null; curr.right = next; } curr = curr.right; } }
补充说明 :
示例代码:
TreeNode node1 = new TreeNode(1);
TreeNode node2 = new TreeNode(2);
TreeNode node3 = new TreeNode(3);
TreeNode node4 = new TreeNode(4);
TreeNode node5 = new TreeNode(5);
TreeNode node6 = new TreeNode(6);
TreeNode node7 = new TreeNode(7);
node1.setLeft(node2);
node1.setRight(node3);
node2.setLeft(node4);
node2.setRight(node5);
node3.setLeft(node6);
node3.setRight(node7);
对应树结构:
此题的关键解法在于需要把非父子节点的两节点,连接起来。若不能进入while (predecessor.right != null) {判断条件内,此种情况curr
类似于图中的节点2,需要连接4,5,若能进入,此种情况curr类似于图中的节点1,需要连接5,3
示例:
在这个二叉树中,有两个左叶子,分别是9和15,所以返回24
private int sum = 0; public int sumOfLeftLeaves(TreeNode root) { getLeftSum(root); return sum; } private void getLeftSum(TreeNode root) { if(root ==null){ return; } if(root.left != null && root.left.left == null && root.left.right == null){ sum = sum + root.left.val; }else{ getLeftSum(root.left); } getLeftSum(root.right); }
示例
输入:[1,null,2,3]
输出:[3,2,1]
public static List<Integer> postorderTraversal1(TreeNode root) { List<Integer> res = new ArrayList<Integer>(); if (root == null) { return res; } Deque<TreeNode> stack = new LinkedList<TreeNode>(); TreeNode prev = null; while (root != null || !stack.isEmpty()) { while (root != null) { stack.push(root); root = root.left; } root = stack.pop(); if (root.right == null || root.right == prev) { res.add(root.val); prev = root; root = null; } else { stack.push(root); root = root.right; } } return res; }
补充说明:
说明示例:
示例:
树A:
树B:
返回true, 因为B与A的一个子树拥有相同的结构和节点值。
public static boolean isSubStructure(TreeNode A, TreeNode B) { if(A == null || B == null){ return false; } return verifyNode(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B); } private static boolean verifyNode(TreeNode main, TreeNode sub) { if(sub == null){ return true; } if(main == null){ return false; } if(main.val == sub.val){ return verifyNode(main.left, sub.left) && verifyNode(main.right, sub.right); }else{ return false; } }
示例:
给定一个链表:1->2->3->4->5, 和k=2. 返回链表 4->5
双指针法:
public ListNode getKthFromEnd(ListNode head, int k){
ListNode quick = head;
ListNode slow = head;
while(k > 0){
quick = quick.next;
k--;
}
while(quick != null){
quick = quick.next;
slow = slow.next;
}
return slow;
}
示例:
输入:n = 3
输出:5
解法1:
public int numTrees(int n) {
int [] fn = new int[n+1];
fn[0] =1;
fn[1] =1;
for(int i=2;i<=n;i++){
for(int j=1;j<=i;j++){
fn[i] += fn[j-1] * fn[i-j];
}
}
return fn[n];
}
补充说明:
解法2:
Map<Integer, Integer> resultMap = new HashMap(); public int numTrees(int n) { resultMap.put(0, 1); resultMap.put(1, 1); return getRes(n); } private int getRes(int n) { if (resultMap.containsKey(n)) { return resultMap.get(n); } int temp = 0; for (int i = 1; i <= n; i++) { int cur = getRes(i - 1) * getRes(n - i); temp = temp + cur; } resultMap.put(n, temp); return temp; }
示例:
输入:[3,2,3,null,3,null,1]
输出: 7
解释:小偷一晚能够偷取的最高金额= 3 + 3 + 1 = 7.
public int rob(TreeNode root) {
int[] rootStatus = dfs(root);
return Math.max(rootStatus[0], rootStatus[1]);
}
public int[] dfs(TreeNode node) {
if (node == null) {
return new int[]{0, 0};
}
int[] l = dfs(node.left);
int[] r = dfs(node.right);
int selected = node.val + l[1] + r[1];
int notSelected = Math.max(l[0], l[1]) + Math.max(r[0], r[1]);
return new int[]{selected, notSelected};
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。