513.找树左下角的值
文字讲解:二叉树的层序遍历
视频讲解:二叉树的层序遍历
状态:用的层序遍历,先获取树的高度,然后层序遍历到最后一层,返回最后一层第一个元素;
思路:
用的层序遍历,先获取树的高度,然后层序遍历到最后一层,返回最后一层第一个元素;
代码:
class Solution {
public int findBottomLeftValue(TreeNode root) {
int height = getHeight(root);
//层序遍历到最后一层将第一个元素返回
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int depth = 0;
while (!queue.isEmpty()) {
depth++;
int len = queue.size();
while (len > 0) {
TreeNode poll = queue.poll();
if (depth == height) {
return poll.val;
}
if (poll.left != null) {
queue.offer(poll.left);
}
if (poll.right != null) {
queue.offer(poll.right);
}
len--;
}
}
return 0;
}
//先获取二叉树的最大深度
public int getHeight(TreeNode node) {
if (node == null) {
return 0;
}
int leftHeight = getHeight(node.left);
int rightHeight = getHeight(node.right);
return Math.max(leftHeight, rightHeight) + 1;
}
}
112.路径之和
文字讲解:路劲之和
视频讲解:代码随想录-路径之和
状态:这题如果理解了昨天的二叉树的所有路径一题,可以举一反三写出这题
思路:
1、回溯算法完成;
代码:
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) {
return false;
}
int[] arr= new int[2];
arr[1] = targetSum;
return calculatePathSum(root, arr);
}
public boolean calculatePathSum(TreeNode node, int[] arr) {
arr[0] += node.val;
if (node.left == null && node.right == null) { //收集
return arr[0] == arr[1];
}
boolean leftFlag = false;
boolean rightFlag = false;
if (node.left != null) { //向左查找
leftFlag = calculatePathSum(node.left, arr);
arr[0]-=node.left.val;
}
if (node.right != null) { //向左查找
rightFlag = calculatePathSum(node.right, arr);
arr[0]-=node.right.val;
}
return leftFlag || rightFlag;
}
}
113.路径之和II
代码:
class Solution {
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
//回溯查找
LinkedList<Integer> tempList = new LinkedList<>();
List<List<Integer>> result = new LinkedList<>();
if (root == null) {
return result;
}
collectPath(root, tempList, result, targetSum);
return result;
}
public void collectPath(TreeNode node,LinkedList<Integer> tempList, List<List<Integer>> result, int targetSum) {
tempList.offer(node.val);
if (node.left == null && node.right == null) {
//开始收集;
List<Integer> list = collectParam(tempList, targetSum);
if (list != null) result.add(list);
return;
}
if (node.left != null) {
collectPath(node.left, tempList, result, targetSum);
tempList.pollLast();
}
if (node.right != null) {
collectPath(node.right, tempList, result, targetSum);
tempList.pollLast();
}
}
public List<Integer> collectParam(List<Integer> list, int targetSum) {
int sum = 0;
for (Integer integer : list) {
sum+=integer;
}
if (sum != targetSum) {
return null;
}
List<Integer> result = new ArrayList<>(list.size());
for (Integer param : list) {
result.add(param);
}
return result;
}
}
106.从中序与后序遍历序列构造二叉树
文字讲解:从中序与后序遍历序列构造二叉树
视频讲解: 从中序与后序遍历序列构造二叉树
状态:代码先照着视频里的讲解和文档讲解写完了,这一题有点难呀;
思路:
- 第一步:如果数组大小为零的话,说明是空节点了。
- 第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。
- 第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点
- 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
- 第五步:切割后序数组,切成后序左数组和后序右数组
- 第六步:递归处理左区间和右区间
代码:
class Solution {
Map<Integer, Integer> map = new HashMap<>();
public TreeNode buildTree(int[] inorder, int[] postorder) {
for (int i = 0; i < inorder.length; i++) {
map.put(inorder[i], i);
}
//采用左闭右开的数组遍历原则
return buildTreeByIndex(inorder, 0, inorder.length, postorder, 0, postorder.length);
}
public TreeNode buildTreeByIndex(int[] inorder, int inBegin, int inEnd, int[] postorder, int postBegin, int postEnd) {
if (inBegin >= inEnd && postBegin >= postEnd) {
return null;
}
//获取后序遍历数组的最后一个元素
int rootVal = postorder[postEnd - 1];
TreeNode root = new TreeNode(rootVal);
//获取root节点在中序节点的下标位置;
Integer rootIndex = map.get(rootVal);
//设置左节点;将中序数组用root节点的下标分成左右两个数组来操作,同样处理以后一定要坚持左闭右开的原则;
//后序数组按照中序切割后左侧数组的长度来计算
int leftTreeLen = rootIndex - inBegin;
root.left = buildTreeByIndex(inorder, inBegin, rootIndex,
postorder, postBegin, postBegin + leftTreeLen);
//这里注意是左闭右开
root.right = buildTreeByIndex(inorder, rootIndex+1, inEnd,
postorder, postBegin+leftTreeLen, postEnd-1);
return root;
}
}