1 找树左下角的值
题目
给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。
代码
//递归
class Solution {
int maxdeep=-1;
int res;
public int findBottomLeftValue(TreeNode root) {
traversal(root,0);
return res;
}
public void traversal(TreeNode node,int deep){
if(node.left==null && node.right==null){
if(deep>maxdeep){
maxdeep=deep;
res=node.val;
}
return;
}
if(node.left!=null) traversal(node.left,deep+1);
if(node.right!=null) traversal(node.right,deep+1);
return;
}
}
//迭代
class Solution {
public int findBottomLeftValue(TreeNode root) {
int result;
Queue<TreeNode> queue=new LinkedList<>();
queue.offer(root);
result=root.val;
while(!queue.isEmpty()){
int size=queue.size();
for(int i=0;i<size;i++){
TreeNode temp=queue.poll();
if(i==0) result=temp.val;
if(temp.left!=null) queue.offer(temp.left);
if(temp.right!=null) queue.offer(temp.right);
}
}
return result;
}
}
总结
递归:最开始的maxdeep要设为-1,因为当树只有一个结点时,deep=0;
迭代:记录每层出队的第一个结点,就是每层最左的结点。
2 路径之和
题目
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。
叶子节点 是指没有子节点的节点。
代码
//递归
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if(root==null) return false;
return traversal(root,root.val,targetSum);
}
public boolean traversal(TreeNode node,int pathsum,int targetSum){
if(node.left==null && node.right==null && pathsum==targetSum) return true;
if(node.left==null && node.right==null) return false;
boolean left,right;
if(node.left!=null) {
left=traversal(node.left,pathsum+node.left.val,targetSum);
if(left) return true;
}
if(node.right!=null){
right=traversal(node.right,pathsum+node.right.val,targetSum);
if(right) return true;
}
return false;
}
}
//迭代
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if(root==null) return false;
Stack<TreeNode> st1=new Stack<>();
Stack<Integer> st2=new Stack<>();
st1.push(root);st2.push(root.val);
while(!st1.isEmpty()){
TreeNode temp=st1.pop();
Integer sum=st2.pop();
if(temp.left==null &&temp.right==null && sum==targetSum) return true;
if(temp.left!=null) {
st1.push(temp.left);
st2.push(sum+temp.left.val);
}
if(temp.right!=null){
st1.push(temp.right);
st2.push(sum+temp.right.val);
}
}
return false;
}
}
总结
刚开始的想法就是把路径上的点加起来与目标值比较,写的过程是有点混乱的。
看了参考代码,用减法,是我没想到的。递归不好写,终止条件我还是看了参考代码写的。迭代好写,好理解。
3 路径之和-ii
题目
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
叶子节点 是指没有子节点的节点。
代码
//迭代
class Solution {
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
List<List<Integer>> res=new ArrayList<>();
if(root==null) return res;
Stack<TreeNode> st1=new Stack<>();//存经历的结点
Stack<Integer> st2=new Stack<>();//存根节点到对应结点的路径总和
Stack<List<Integer>> st3=new Stack<>();//存根节点到对应节点的路径
List<Integer> path=new ArrayList();
path.add(root.val);
st1.push(root);
st3.push(path);
st2.push(root.val);
while(!st1.isEmpty()){
List<Integer> path1=new ArrayList();
path1=st3.pop();
TreeNode temp=(TreeNode)st1.pop();
int sum=st2.pop();
if(temp.left==null && temp.right==null &&sum==targetSum){
res.add(path1);
}
if(temp.left==null && temp.right==null){
}
if(temp.right!=null){
st1.push(temp.right);
List<Integer> path_r=new ArrayList(path1);
path_r.add(temp.right.val);
st3.push(path_r);
st2.push(sum+temp.right.val);
}
if(temp.left!=null){
st1.push(temp.left);
List<Integer> path_l=new ArrayList(path1);
path_l.add(temp.left.val);
st3.push(path_l);
st2.push(sum+temp.left.val);
}
}
return res;
}
}
//递归
class Solution {
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
List<List<Integer>> res=new ArrayList<>();
if(root==null) return res;
List<Integer> path=new LinkedList<>();
preorderdfs(root,targetSum,res,path);
return res;
}
public void preorderdfs(TreeNode root,int targetSum,List<List<Integer>> res,List<Integer> path){
path.add(root.val);
if(root.left==null && root.right==null){
if(targetSum-root.val==0){
res.add(new ArrayList<>(path));
}
return;
}
if(root.left!=null){
preorderdfs(root.left,targetSum-root.val,res,path);
path.remove(path.size()-1);
}
if(root.right!=null){
preorderdfs(root.right,targetSum-root.val,res,path);
path.remove(path.size()-1);
}
}
}
总结
迭代法我真的累了。路径条数对,但路径是全部结点的遍历,找了半天错误,调试好久,居然是list的赋值。最开始我直接path_l=path1,这样是引用赋值,path1会随着path_l变化…
递归 整个逻辑全部串起来,有点复杂。