513.找树左下角的值
思路
层序遍历,遍历完后取出最后一层的第一个值
代码
class Solution {
List<List<Integer>> tlist = new ArrayList<List<Integer>>();
public int findBottomLeftValue(TreeNode root) {
return levelOrder(root);
}
public int levelOrder(TreeNode cur){
int val = 0;//保存最底层最左边节点的值
Deque<TreeNode> q = new ArrayDeque<TreeNode>();
q.addLast(cur);
while(!q.isEmpty()){
int len = q.size();
List<Integer> list = new ArrayList<Integer>();
while(len>0){
TreeNode tnode = q.pollFirst();
list.add(tnode.val);
if(tnode.left!=null) q.addLast(tnode.left);
if(tnode.right!=null) q.addLast(tnode.right);
len--;
}
tlist.add(list);
}
val = tlist.get(tlist.size()-1).get(0);
return val;
}
}
题解思路
有两个关键,一是最后一行,二是最左边,可以通过最大深度的叶子节点判断是最后一行。只有第一次访问最大深度的时候,记录下节点值,按照中左右的顺序,那么访问的必然是最后一行最左边节点的值。
112. 路径总和 113.路径总和ii
思路
通过中序遍历,用一个res来保存最终的结果,只要有一个满足了根节点到叶子节点的路径和等于目标和的,那么就返回true。,并且每次回溯。
代码
class Solution {
int sum = 0;
boolean res = false;
public boolean hasPathSum(TreeNode root, int targetSum) {
if(root == null) return false;
sum += root.val;
if(root.left == null && root.right==null){
if( sum == targetSum)
res = true;
return res;
}
boolean t1 = false;
if(root.left!=null){
t1 = hasPathSum(root.left,targetSum);
sum -= root.left.val;
}
boolean t2 =false;
if(root.right!=null){
t2 = hasPathSum(root.right,targetSum);
sum -= root.right.val;
}
return res;
}
}
106.从中序与后序遍历序列构造二叉树
思路
按照后序遍历的结果的最后一个数字找到中间节点,,然后切割中序遍历的 左边和右边,接着继续按照后续遍历的结果找到左边和右边的中间节点,切割中序遍历的下一个左边和右边…思路应该是递归。
题解思路:
• 第一步:如果数组大小为零的话,说明是空节点了。
• 第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。
• 第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点
• 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
• 第五步:切割后序数组,切成后序左数组和后序右数组
• 第六步:递归处理左区间和右区间
注意中序和前序、中序和后续都可以确定一颗二叉树,而前序和后序不能。
终点是通过下标 不断缩小中序数组和后续数组的范围,不改变原数组。每次获取中间节点的值即可 构造二叉树。
利用一个map确定中序数组的下标
注意要确定是左闭右开:在二分法中切割很重要
代码
class Solution {
Map<Integer, Integer> map; // 方便根据数值查找位置
public TreeNode buildTree(int[] inorder, int[] postorder) {
map = new HashMap<>();
for (int i = 0; i < inorder.length; i++) { // 用map保存中序序列的数值对应位置
map.put(inorder[i], i);
}
return findNode(inorder, 0, inorder.length, postorder,0, postorder.length); // 前闭后开
}
public TreeNode findNode(int[] inorder, int inBegin, int inEnd, int[] postorder, int postBegin, int postEnd) {
// 参数里的范围都是前闭后开
if (inBegin >= inEnd || postBegin >= postEnd) { // 不满足左闭右开,说明没有元素,返回空树
return null;
}
int rootIndex = map.get(postorder[postEnd - 1]); // 找到后序遍历的最后一个元素在中序遍历中的位置
TreeNode root = new TreeNode(inorder[rootIndex]); // 构造结点
int lenOfLeft = rootIndex - inBegin; // 保存中序左子树个数,用来确定后序数列的个数
root.left = findNode(inorder, inBegin, rootIndex,
postorder, postBegin, postBegin + lenOfLeft);
root.right = findNode(inorder, rootIndex + 1, inEnd,
postorder, postBegin + lenOfLeft, postEnd - 1);
return root;
}
}