513.找树左下角的值
题目链接:513. 找树左下角的值 - 力扣(LeetCode)
迭代法:借助队列进行层序遍历
class Solution {
public int findBottomLeftValue(TreeNode root) {
// 层序遍历-迭代
int ans = -1;
if(root == null) return -1;
Queue<TreeNode> que = new LinkedList<>();
que.offer(root);
while(!que.isEmpty()){
int size = que.size();
for(int i = 0; i < size; i++){
TreeNode cur = que.poll();
if(i == 0) ans = cur.val;
if(cur.left != null) que.offer(cur.left);
if(cur.right != null) que.offer(cur.right);
}
}
return ans;
}
}
112.路径总和
回溯法求解,需要注意的是,下面的代码中当进入节点之前就已经把要进入节点的值加上了
class Solution {
boolean flag = false;
public boolean hasPathSum(TreeNode root, int targetSum) {
if(root == null) return false;
hasTargetSum(root, targetSum, root.val);
return flag;
}
public void hasTargetSum(TreeNode root, int targetSum, int sum){
if(root.left == null && root.right == null && sum == targetSum) flag = true; // 终止条件
if(root.left == null && root.right == null) return;
if(root.left != null){
hasTargetSum(root.left, targetSum, sum + root.left.val);
}
if(root.right != null){
hasTargetSum(root.right, targetSum, sum + root.right.val);
}
}
}
113.路径总和ii
题目链接:113. 路径总和 II - 力扣(LeetCode)
和上题是一样采用回溯法的思路求解,需要注意的是,下面的代码中当进入节点之前就已经把要进入节点的值加上了
class Solution {
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
List<List<Integer>> ans = new ArrayList<>();
if(root == null) return ans;
List<Integer> path = new ArrayList<>();
path.add(root.val);
findPath(root, targetSum, root.val, path, ans);
return ans;
}
void findPath(TreeNode root, int targetSum, int sum, List<Integer> path, List<List<Integer>> ans){
// 回溯的终止条件
if(root.left == null && root.right == null){ // 叶子节点
if(sum == targetSum) ans.add(new ArrayList<>(path)); // 符合条件的路径
return;
}
if(root.left != null){
path.add(root.left.val);
findPath(root.left,targetSum,sum + root.left.val, path, ans);
path.remove(path.size() - 1);
}
if(root.right != null){
path.add(root.right.val);
findPath(root.right,targetSum,sum + root.right.val, path, ans);
path.remove(path.size() - 1);
}
}
}
106.从中序与后序遍历序列构造二叉树
题目链接:106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)
首先通过一个map记录中序数组中元素和其对应的下标,然后递归获取后序数组的最后一个元素,通过前面的map确定这个元素在中序数组中的位置,然后根据这个位置,我们就可以对中序序列和后序序列进行分割。
分割后的就变成了两段子数组,继续迭代进行如下操作。该方法的返回值是一个树节点,并且分割后的子数组的迭代结果就是这个树节点的左右孩子。通过迭代就可以将整个树的关联关系创建出来。二叉树也就构造完成了。105题同理
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.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;
}
}
105.从前序和中序遍历序列构造二叉树
题目链接:105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)
class Solution {
Map<Integer,Integer> map;
public TreeNode buildTree(int[] preorder, int[] inorder) {
map = new HashMap<>();
for(int i = 0; i < inorder.length; i++){
map.put(inorder[i], i);
}
return findNode(inorder, 0, inorder.length, preorder, 0, preorder.length);
}
public TreeNode findNode(int[] inorder,int inBegin, int inEnd, int[] preorder, int preBegin, int preEnd){
// 区间是左闭右开的
if(inBegin >= inEnd || preBegin >= preEnd){
return null;
}
int rootIndex = map.get(preorder[preBegin]);
TreeNode root = new TreeNode(inorder[rootIndex]);
int lenOfLeft = rootIndex - inBegin;
root.left = findNode(inorder, inBegin, rootIndex, preorder, preBegin + 1, preBegin + lenOfLeft + 1);
root.right = findNode(inorder, rootIndex + 1, inEnd, preorder, preBegin + lenOfLeft + 1, preEnd);
return root;
}
}