一、[513]找树左下角的值
class Solution {
int maxDepth=Integer.MIN_VALUE;
int res=0;
public int findBottomLeftValue(TreeNode root) {
//递归 depth 0/1均可
traversal(root,1);
return res;
}
void traversal(TreeNode node,int depth){
if(node.left==null&&node.right==null){
if(depth>maxDepth){
maxDepth=depth;
res= node.val;
}
}
if(node.left!=null) {
traversal(node.left, depth + 1);
}
if(node.right!=null) {
traversal(node.right, depth + 1);
}
}
}
层次遍历
public int findBottomLeftValue(TreeNode root) {
//层次遍历
int res=0;
LinkedList<TreeNode> queue=new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
int size = queue.size();
for(int i=0;i<size;i++){
TreeNode node = queue.pop();
//覆盖
if(i==0){
res= node.val;
}
if(node.left!=null){
queue.offer(node.left);
}
if(node.right!=null) {
queue.offer(node.right);
}
}
}
return res;
}
二、[112]路径总和[113] 路径总和ii
重点:List为引用传递,指向同一个内存地址
因此:需暂存tmp(List),再赋值给res,否则只存入了根节点,其他元素都remove了。
class Solution {
//回溯
boolean flag=false;
public boolean hasPathSum(TreeNode root, int targetSum) {
if(root==null){
return false;
}
exist(root,targetSum,0);
return flag;
}
void exist(TreeNode node,int targetSum,int sum){
sum += node.val;
if(node.left==null&&node.right==null){
if(sum==targetSum){
flag=true;
}
return;
}
if(node.left!=null) {
exist(node.left,targetSum,sum);
}
if(node.right!=null){
exist(node.right,targetSum,sum);
}
}
}
class Solution {
List<List<Integer>> res=new ArrayList<>();
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
if(root==null){
return res;
}
List<Integer> tmp=new ArrayList<>();
//List为引用传递
//类似于[257]
exist(root,targetSum,0,tmp);
return res;
}
void exist(TreeNode node,int targetSum,int sum, List<Integer> tmp){
sum += node.val;
tmp.add(node.val);
if(node.left==null&&node.right==null){
if(sum==targetSum){
//暂存tmp,tmp为引用传递
List<Integer> list=new ArrayList<>(tmp);
res.add(list);
}
return;
}
if(node.left!=null) {
exist(node.left,targetSum,sum,tmp);
tmp.remove(tmp.size()-1);
}
if(node.right!=null){
exist(node.right,targetSum,sum,tmp);
tmp.remove(tmp.size()-1);
}
}
}
三、[106]从中序与后序遍历序列构造二叉树[105]从前序与中序遍历序列构造二叉树
中序点左点size和后续的左的size一定是一样的
如果你知道中序的左部分的size,就可以靠size去切割后序
因为中序和后续都是先左后右
有点难度。
class Solution {
Map<Integer, Integer> map;
public TreeNode buildTree(int[] inorder, int[] postorder) {
if(postorder.length == 0 || inorder.length == 0)
return null;
map = new HashMap<>();
//用map保存中序序列的数值对应位置
for (int i = 0; i < inorder.length; i++) {
map.put(inorder[i], i);
}
return traversal(inorder,0,inorder.length,postorder,0,postorder.length);
}
TreeNode traversal(int[] inorder,int inBegin,int inEnd, int[] postorder,int postBegin,int postEnd){
//不满足左闭右开,说明没有元素,返回空树
if (inBegin >= inEnd || postBegin >= postEnd) {
return null;
}
//注意 postorder[postEnd - 1]; postEnd-1 而不是postorder.length-1
//找了半个小时的错误!!!
int rootValue = postorder[postEnd - 1];
TreeNode root=new TreeNode(rootValue);
//分割
//中序 [0,i) [i+1,inEnd) i为根节点的索引
/*int index;
for(index=is;index< ie;index++){
System.out.println(index);
if(inorder[index]==rootValue){
break;
}
}*/
int index=map.get(postorder[postEnd - 1]);;
//后序
//左边长度为index(index为中间节点的索引)
int len=index-inBegin;
root.left=traversal(inorder,inBegin,index,
postorder,postBegin,postBegin+len);
root.right=traversal(inorder,index+1,inEnd,
postorder,postBegin+len, postEnd-1);
return root;
}
}