刷题日记16
今天依然是二叉树,巩固一下带回溯的递归法,还有从中序遍历、后序遍历中创建二叉树。
从中序遍历和后序遍历能还原唯一的二叉树,从中序遍历和前序遍历能还原唯一的二叉树。
513. 找树左下角的值
递归法
class Solution {
public int maxDepth = Integer.MIN_VALUE;
public int result;
public int findBottomLeftValue(TreeNode root) {
find(root, 0);
return result;
}
public void find(TreeNode root, int depth){
if (root == null) return;
depth++;
if(depth > maxDepth){
maxDepth = depth;
result = root.val; // 中
}
find(root.left, depth); // 左
find(root.right, depth); // 右
}
}
层序遍历法
class Solution {
public int findBottomLeftValue(TreeNode root) {
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
int result = 0;
while(!q.isEmpty()){
int len = q.size();
for(int i = 0; i < len;i++){
TreeNode node = q.poll();
if(i == 0) result = node.val;
if(node.left != null) q.offer(node.left);
if(node.right != null) q.offer(node.right);
}
}
return result;
}
}
112. 路径总和
class Solution {
public Boolean res = false;
public boolean hasPathSum(TreeNode root, int targetSum) {
findPath(root, 0, targetSum);
return res;
}
public void findPath(TreeNode root, int sum, int target){
if(root == null) return;
sum += root.val; //中
if(root.left == null && root.right == null && sum == target){
res = true;
}
findPath(root.left, sum, target); //左
findPath(root.right, sum, target); //右
}
}
113. 路径总和 II
class Solution {
public List<List<Integer>> res = new LinkedList<>();
public List<Integer> path = new LinkedList<>();
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
findPath(root, 0, targetSum);
return res;
}
public void findPath(TreeNode root, int sum, int target){
if(root == null) return;
path.add(root.val); //中
sum += root.val;
if(root.left == null && root.right == null && sum == target){
res.add(new ArrayList(path));
}
findPath(root.left, sum, target); // 左
findPath(root.right, sum, target); // 右
path.remove(path.size()-1); //回溯path, sum不需要回溯因为它是临时变量
}
}
106. 从中序与后序遍历序列构造二叉树
主要思路就是后序遍历的最后一个值就是根节点,我们只需要从后序遍历入手,再找到这个值在中序遍历的索引(需要一个哈希表),就能把中序遍历分成3份,分变为[左子树,根节点,右子树],再递归创建右子树和左子树,就能创建出整个树。
值得注意的是,一定要先创建右子树,因为只能从右子树中得到根节点,再得到所有右子树的根节点后,左子树的索引才能确定。
class Solution {
public HashMap<Integer, Integer> map = new HashMap<>();
public int postIndex;
public int[] inorder;
public int[] postorder;
public TreeNode buildTree(int[] inorder, int[] postorder) {
this.inorder = inorder;
this.postorder = postorder;
postIndex = postorder.length - 1;
int i = 0;
for(int n: inorder){
map.put(n, i++);
}
return build(0, inorder.length - 1);
}
public TreeNode build(int inLeft, int inRight){
if(inLeft > inRight) return null;
int val = postorder[postIndex--];
TreeNode root = new TreeNode(val);
int index = map.get(val);
root.right = build(index + 1, inRight);
root.left = build(inLeft, index - 1);
return root;
}
}
105. 从前序与中序遍历序列构造二叉树
class Solution {
public HashMap<Integer, Integer> map = new HashMap<>();
public int[] preorder;
public int[] inorder;
public int preIndex;
public TreeNode buildTree(int[] preorder, int[] inorder) {
this.preorder = preorder;
this.inorder = inorder;
preIndex = 0;
int i = 0;
for(int n : inorder){
map.put(n, i++);
}
return build(0, preorder.length - 1);
}
public TreeNode build(int inLeft, int inRight){
if(inLeft > inRight) return null;
int val = preorder[preIndex++];
TreeNode root = new TreeNode(val);
int index = map.get(val);
root.left = build(inLeft, index - 1);
root.right = build(index + 1, inRight);
return root;
}
}