513:找树左下角的值
1、迭代法:
通过层序遍历,可以很容易的找到左下角的值。
class Solution {
public int findBottomLeftValue(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int val = 0;
while (!queue.isEmpty()) {
List<Integer> list = new LinkedList<>();
int len = queue.size();
for (int i = 0; i < len; i++) {
TreeNode node = queue.poll();
list.add(node.val);
if (node.left!=null) {
queue.offer(node.left);
}
if (node.right!=null) {
queue.offer(node.right);
}
}
val = list.get(0);
}
return val;
}
}
2、递归法:
1)递归函数参数和返回值:传入参数分别为结点和当前深度,通过全局变量来记录最大深度和左下角的值,因此没有返回值。
2)递归终止条件:当当前传入结点的左右子节点都为空的时候,如果当前深度大于所记录的最大深度,则更新最大深度值和result值并返回。
3)单层递归逻辑:遍历当前节点的左子树和右子树的最大深度对应的节点值。
class Solution {
private int maxDepth = -1;
private int result = 0;
public int findBottomLeftValue(TreeNode root) {
result = root.val;
find(root, 0);
return result;
}
private void find(TreeNode root, int depth) {
if (root==null) {
return;
}
if (root.left==null && root.right==null) {
if (depth>maxDepth) {
maxDepth = depth;
result = root.val;
}
return;
}
if (root.left!=null) {
depth++;
find(root.left, depth);//递归
depth--;
}
if (root.right!=null) {
depth++;
find(root.right, depth);//递归
depth--;
}
}
}
112:路径总和
递归法:这里一开始的时候写的不对,后面看了题解之和发现是如下部分没有处理好
if (root.left!=null) {
if (sum(root.left, tarhetSum, curSum+root.val)) {
return true;
}
}
最开始写的时候直接写的
if (root.left!=null) {
sum(root.left, tarhetSum, curSum+root.left.val);
}
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
return sum(root, targetSum, 0);
}
public boolean sum(TreeNode root, int tarhetSum, int curSum) {
if (root==null) {
return false;
}
if (root.left==null && root.right==null) {
if ((curSum+root.val)==tarhetSum) {
return true;
}
}
if (root.left!=null) {
if (sum(root.left, tarhetSum, curSum+root.val)) {
return true;
}
}
if (root.right!=null) {
if (sum(root.right, tarhetSum, curSum+root.val)) {
return true;
}
}
return false;
}
}
迭代法:仿照257:二叉树所有路径写的
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root==null) {
return false;
}
Stack<Object> stack = new Stack<>();
stack.push(root);
stack.push(root.val);
while (!stack.isEmpty()) {
Integer val = (Integer) stack.pop();
TreeNode node = (TreeNode) stack.pop();
if (val==targetSum && node.left==null && node.right==null) {
return true;
}
if (node.left!=null) {
stack.push(node.left);
stack.push(node.left.val+val);
}
if (node.right!=null) {
stack.push(node.right);
stack.push(node.right.val+val);
}
}
return false;
}
}
113:路径总和II
这个题和112的区别在于要输出所有的路径,这里需要注意的是递归出口的时候得重新new一个ArrayList对象,貌似是因为Java是引用传递,那样当list回溯的话,值会发生改变。
class Solution {
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
List<List<Integer>> res = new ArrayList<>();
List<Integer> list = new ArrayList<>();
if(root==null) return res;
list.add(root.val);
path(root, targetSum-root.val, list, res);
return res;
}
public void path(TreeNode root, int targetSum,
List<Integer> list, List<List<Integer>> res) {
if (root==null) {
return;
}
if (root.left==null && root.right==null) {
if (targetSum==0) {
res.add(new ArrayList<>(list));
}
return;
}
if (root.left!=null) {
list.add(root.left.val);
path(root.left, targetSum-root.left.val, list, res);
list.remove(list.size()-1);
}
if (root.right!=null) {
list.add(root.right.val);
path(root.right, targetSum-root.right.val, list, res);
list.remove(list.size()-1);
}
}
}
106:从中序和后序遍历序列构造二叉树
第一步:先从后序遍历中找到根节点;第二步:根据根节点在中序遍历中找到对应位置,计算出左子树的长度;第三步根据左子树的长度调节下一次遍历的begin、end、left和right。遵循左闭右开原则。
class Solution {
public TreeNode buildTree(int[] inorder, int[] postorder) {
if (inorder.length==0 || postorder.length==0) {
return null;
}
return build(inorder, 0, inorder.length, postorder, 0, postorder.length);
}
public TreeNode build(int[] inorder, int begin, int end,
int[] postorder,int left, int right) {
if (begin>=end && left>=right) {
return null;
}
int v = postorder[right-1];
TreeNode root = new TreeNode(v);
int leftLen = -1;
for (int i = begin; i < end; i++) {
if (inorder[i]==v) {
leftLen = i-begin;
}
}
root.left = build(inorder, begin, begin+leftLen, postorder, left, left+leftLen);
root.right = build(inorder, begin+leftLen+1, end, postorder, left+leftLen, right-1);
return root;
}
}
105:从前序和中序遍历序列构造二叉树
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
if (preorder.length==0 || inorder.length==0) {
return null;
}
return build(preorder, 0, preorder.length, inorder, 0, inorder.length);
}
public TreeNode build(int[] preorder, int begin, int end,
int[] inorder,int left, int right) {
if (begin>=end && left>=right) {
return null;
}
int v = preorder[begin];
TreeNode root = new TreeNode(v);
int leftLen = -1;
for (int i = left; i < right; i++) {
if (inorder[i]==v) {
leftLen = i-left;
}
}
root.left = build(preorder, begin+1, begin+leftLen+1, inorder, left, left+leftLen);
root.right = build(preorder, begin+leftLen+1, end, inorder, left+leftLen+1, right);
return root;
}
}