找树左下角的值
本题属于二叉树的层序遍历的延申题,可以在层序遍历模板上修改即可。
每次res每层都覆盖为最新的最左边的数!
//迭代法
class Solution {
public int findBottomLeftValue(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int res = 0;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode poll = queue.poll();
//res每层都覆盖为最新的最左边的数
//直到最后一层
if (i == 0) {
res = poll.val;
}
if (poll.left != null) {
queue.offer(poll.left);
}
if (poll.right != null) {
queue.offer(poll.right);
}
}
}
return res;
}
}
路径总和
1)判断是否存在
递归+回溯
递归的返回值时boolean
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) {
return false;
}
return traversal(root, targetSum - root.val); // 初始递归调用
}
public boolean traversal(TreeNode cur, int count) {
// 如果到达叶子节点,检查路径和是否为目标值
if (cur.left == null && cur.right == null) {
return count == 0; // 当路径和为目标值时返回true
}
// 左子树递归
if (cur.left != null) { // 左节点存在
count -= cur.left.val; // 处理当前节点
if (traversal(cur.left, count)) { // 递归调用左子树
return true;
}
count += cur.left.val; // 回溯,撤销处理
}
// 右子树递归
if (cur.right != null) { // 右节点存在
count -= cur.right.val; // 处理当前节点
if (traversal(cur.right, count)) { // 递归调用右子树
return true;
}
count += cur.right.val; // 回溯,撤销处理
}
return false; // 未找到符合条件的路径,返回false
}
}
2)写出具体的路径
递归+回溯,递归不需要返回值,需要设置全局的结果变量来接收和更新结果。
class Solution {
List<List<Integer>> result;
List<Integer> path;
public List<List<Integer>> pathSum (TreeNode root,int targetSum) {
result = new ArrayList<>();
path = new ArrayList<>();
travesal(root, targetSum);
return result;
}
private void travesal(TreeNode root, int count) {
if (root == null) return;
path.add(root.val);
count -= root.val;
if (root.left == null && root.right == null && count == 0) {
//通过 new ArrayList<>(path) 创建 path 的一个副本,并将其添加到 result 中. 这样可以确保 result 中的路径不会被后续的回溯操作影响.
result.add(new ArrayList<>(path));
}
travesal(root.left, count);
travesal(root.right, count);
path.remove(path.size()-1); // 回溯
}
}
从中序与后序遍历序列构造二叉树
根据中序和后序可以唯一确定一个二叉树。
中序: 左根右
后序:左右根
所以后序最后一个可以确定根节点
一层一层切割-》递归
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保存中序序列的数值对应位置
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;
}
}