LeetCode 513 找树左下角的值
本题思路:找到最底层最左边的值,我的想法是,利用层序遍历,分别存储每一层的值,然后取最后一层的第一个元素就是我们想得到值。
class Solution {
public int findBottomLeftValue(TreeNode root) {
List<List<Integer>> res = new ArrayList();
Deque<TreeNode> queue = new ArrayDeque();
queue.offer(root);
while(!queue.isEmpty()){
int size = queue.size();
List<Integer> list = new ArrayList();
while(size-- != 0){
TreeNode cur = queue.poll();
list.add(cur.val);
if(cur.left!=null){
queue.offer(cur.left);
}
if(cur.right!=null){
queue.offer(cur.right);
}
}
res.add(list);
}
return res.get(res.size()-1).get(0);
}
}
LeetCode 112 路径总和
本题思路: 利用递归来完成。 保存每一条路径的节点和。然后判断是否存在一个 sum 等于 targetSum,有的就添加到 res 中。
注意递归的时候,要回溯!
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if(root == null){
return false;
}
List<Integer> paths = new ArrayList();
List<Integer> res = new ArrayList();
travel(root,paths,res,targetSum);
if(res.size() > 0){
return true;
}
return false;
}
public void travel(TreeNode root, List<Integer> paths, List<Integer> res,int targetSum){
// 先把根节点放入Paths中
paths.add(root.val);
if(root.left == null && root.right == null){
int sum = 0;
for(int i = 0; i < paths.size(); i++){
sum += paths.get(i);
}
if(sum == targetSum){
res.add(sum);
}
return;
}
if(root.left != null){
travel(root.left,paths,res,targetSum);
paths.remove(paths.size()-1);
}
if(root.right != null){
travel(root.right,paths,res,targetSum);
paths.remove(paths.size()-1);
}
}
}
LeetCode 113 路径总和||
本题思路: 和上一题一模一样,只不过我们再判断 sum == targetSum 之后,结果集存的是路径
注意:需要回溯
class Solution {
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
List<List<Integer>> res = new ArrayList();
List<Integer> paths = new ArrayList();
if(root == null){
return res;
}
travel(root,paths,res,targetSum);
return res;
}
public void travel(TreeNode root, List<Integer> paths, List<List<Integer>> res,int targetSum){
paths.add(root.val);
if(root.left == null && root.right == null){
List<Integer> ans = new ArrayList();
int sum = 0;
for(int i = 0; i < paths.size(); i++){
ans.add(paths.get(i));
sum += paths.get(i);
}
// 路径和符合要求,才添加该路径
if(sum == targetSum){
res.add(ans);
}
return;
}
if(root.left != null){
travel(root.left,paths,res,targetSum);
paths.remove(paths.size()-1);
}
if(root.right != null){
travel(root.right,paths,res,targetSum);
paths.remove(paths.size()-1);
}
}
}
LeetCode 106 从中序与后序遍历构造二叉树
本题思路:利用后序遍历可以直到根节点的位置,而根据中序遍历,可以根据在后序遍历数组中的根节点位置,将中序数组分割成 左树和右树。
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 static TreeNode build(int[] inorder, int startInorder,int endInorder, int[] postorder,int startPostorder,int endPostorder){
// 如果后序数组为空,说明遍历完,直接返回 null
if(startPostorder == endPostorder){
return null;
}
// 此处定义左闭右开
int rootValue = postorder[endPostorder-1];
TreeNode root = new TreeNode(rootValue);
if(postorder.length == 1){
return root;
}
int index;
// 从中序数组中找节点下标
for(index = startInorder; index < inorder.length; index++){
if(inorder[index] == rootValue){
break;
}
}
int leftstartInorder = startInorder;
int leftendInorder = index;
int rightstartInorder = index+1;
int rightendInoreder = endInorder;
int leftstartpostorder = startPostorder ;
int leftendpostorder = startPostorder + (index - startInorder);
int rightstartpostorder = leftendpostorder;
int rightendpostorder = endPostorder-1;
root.left = build(inorder,leftstartInorder,leftendInorder,postorder,leftstartpostorder,leftendpostorder);
root.right = build(inorder,rightstartInorder,rightstartInorder,postorder,rightstartpostorder,rightendpostorder);
return root;
}
}
注意: 在进行数组分割的时候,因为只有分割中序数组之后,才知道左右子树的元素个数,才能分割后序数组
- 先分割中序数组
- 再分割后序数组
LeetCode 105 从前序与后序遍历构造二叉树
本题思路: 和上题思路一样,只不过分割数组的时候不太一样
注意:
- 先分割中序数组
- 再分割前序数组
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preorder.length == 0 || inorder.length == 0){
return null;
}
return build(inorder,0,inorder.length,preorder,0,preorder.length);
}
public TreeNode build(int[] inorder, int startInorder,int endInorder, int[] preorder, int startPreorder,int endPreorder){
// 找到出口
if(startPreorder == endPreorder){
return null;
}
int rootValue = preorder[startPreorder];
TreeNode root = new TreeNode(rootValue);
if(preorder.length == 1){
return root;
}
int index = 0;
for(index = startInorder; index < inorder.length; index++){
if(inorder[index] == rootValue){
break;
}
}
// 分割中序数组
int leftstartinorder = startInorder;
int leftendinorder = index;
int rightstartinorder = index+1;
int rightendinorder = endInorder;
// 分割前序数组
int leftstartpreorder = startPreorder+1;
int leftendpreorder = leftstartpreorder + (index - startInorder);
int rightstartpreorder = leftendpreorder;
int rightendpreorder = endPreorder;
root.left = build(inorder,leftstartinorder,leftendinorder,preorder,leftstartpreorder,leftendpreorder);
root.right = build(inorder,rightstartinorder,rightendinorder,preorder,rightstartpreorder,rightendpreorder);
return root;
}
}