LeetCode116 填充每个节点的下一个右侧节点指针
题目
给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
初始状态下,所有 next 指针都被设置为 NULL。
提示:
- 你只能使用常量级额外空间。
- 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。
-
思路1:
递归的理解!!!!多理解几遍!!!
代码1:
public Node connect(Node root) {
if(root==null)
return null;
//如果左右节点都存在,那么左子节点的next=右子节点
if(root.left!=null&&root.right!=null)
root.left.next=root.right;
//如果root是左节点,那么root.next是右节点。如果右节点不为空并且右节点存在左子节点,
//那么左节点的右儿子的next指向右节点的左儿子
if(root.next!=null&&root.right!=null&&root.next.left!=null)
root.right.next=root.next.left;
//递归
connect(root.left);
connect(root.right);
return root;
}
思路2:
代码2:
public Node connect(Node root) {
//使用层次遍历,利用辅助队列
//队列特性:先进先出,所以可以用于树的层次遍历
if(root==null)
return null;
Queue<Node> queue = new LinkedList<>();
queue.add(root);
//当队列中含有节点的时候
while(!queue.isEmpty()) {
int n = queue.size();
//每次开始新的一层处理时,pre会重新置为null
Node pre = null;
while(n>0) {
//弹出队首的节点,处理该节点的next域
Node cur = queue.poll();
//当开始新的一层处理时,将cur置为pre,cur.next为队列中下一次弹出的对象
if(pre==null)
pre = cur;
else { //如果pre不为空,那么pre的next域指向cur;
pre.next=cur;
pre=pre.next; //pre指向cur。
}
if(cur.left!=null)
queue.add(cur.left);
if(cur.right!=null)
queue.add(cur.right);
//n写在while(n>0)里面,每次处理的是同层的节点数
//该层节点处理完之后,n=0,退出内层循环,但是此时queue中已经添加了下层的节点,所以queue.size>0,更新n开始新一轮的下层处理
n--;
}
}
return root;
}
LeetCode117 填充每个节点的下一个右侧节点指针 II
题目:
在LeetCode的基础上,给定一个任意二叉树。填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
初始状态下,所有 next 指针都被设置为 NULL。
提示:
你只能使用常量级额外空间。
使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。
思路1:
利用LeetCode116的层次遍历思想,利用队列实现,一模一样的代码,但是不满足恒定空间
思路2:
=-=看不懂下次再说吧
代码:
LeetCode 113路径总和II
题目:
给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。
说明: 叶子节点是指没有子节点的节点。
思路:
代码:
List<List<Integer>> res = new ArrayList<List<Integer>>();
public List<List<Integer>> pathSum(TreeNode root, int sum) {
helper(root,sum,new ArrayList<Integer>());
return res;
}
private void helper(TreeNode root, int target,ArrayList<Integer> list){
//如果是个空树,直接返回null;
if(root==null) return;
list.add(root.val);
//如果是叶子节点并且在和为sum的路径上,那么将list中并添加到res中
if(root.left==null&&root.right==null&&target==root.val)
res.add(list);
//用同样的一个list2保存list,不然数据会串
ArrayList<Integer> list2 = new ArrayList<>(list);
if(root.left!=null)
helper(root.left,target-root.val,list);
if(root.right!=null)
helper(root.right,target-root.val,list2);
}
/*
不新建list2只处理list的方法,差不多
*/
private void helper(TreeNode root, int target,ArrayList<Integer> list){
//如果是个空树,直接返回null;
if(root==null) return;
list.add(root.val);
if(root.left!=null)
helper(root.left,target-root.val,list);
if(root.right!=null)
helper(root.right,target-root.val,list);
if(root.left==null && root.right==null){
if(target==root.val)
//此处必须new一个并传入list,因为list在返回时会remove,
//如果不是new的话,传出的list永远是空值
res.add(new ArrayList<Integer>(list));
}
//每返回一次,删掉一个节点,确保每次返回的都是属于该层的路径,不包含下层阶段
list.remove(list.size()-1);
}
LeetCode112
题目
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
说明: 叶子节点是指没有子节点的节点。
思路
递归
boolean的默认值是false
代码
public boolean hasPathSum(TreeNode root, int sum) {
if(root==null)
return false;
if(root.left==null && root.right ==null&&root.val == sum )
return true;
return hasPathSum(root.left,sum-root.val)||hasPathSum(root.right,sum-root.val);
}