二叉树结点的深度是指当前结点到根节点的海拔;前序求深度
二叉树结点的高度是当前结点到最远叶子结点的海拔;后序求高度
513.找树左下角的值
题目链接:. - 力扣(LeetCode)
思路:最深一层的最左侧的那个结点
可以用层序遍历,遍历每一层时,保存第一个结点,最后就是最左结点啦.如何保存第一个呢
public int findBottomLeftValue(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int num=0;
while(!queue.isEmpty()) {
int size = queue.size();
int count = 1;
for(int i=0;i<size;i++) {
TreeNode node = queue.poll();
if(node.left != null)queue.offer(node.left);
if(node.right != null)queue.offer(node.right);
if(i == 0) num = node.val;
}
}
// findTarget(root,0);
return num;
}
递归法:
求最大深度时的最左结点;用递归让最左边先被遍历,也是用一个depth和result来限定每层第一个结点
public void findTarget(TreeNode node,int depth) {
if(node.left == null && node.right == null) {
if(depth > maxDepth) {
maxDepth = depth;
result = node.val;
}
return;
}//中
if(node.left != null) {//左
depth++;
findTarget(node.left,depth);
depth--;
}
if(node.right != null) {//右
depth++;
findTarget(node.right,depth);
depth--;
}
}
112. 路径总和
题目链接:. - 力扣(LeetCode)
思路:要看所有从根节点到叶结点的路径值和是否为目标值
递归: 这里递归函数的含义是看该节点下所有路径是否满足
- 参数返回值:参数为结点和总和;返回值是boolean类型
- 终止条件是当前结点为叶结点且总和与目标相等,返回true,如果只是叶结点,就返回false
- 单层逻辑(推卸责任的过程):看该结点左右孩子下的路径是否满足
public boolean isEqual(TreeNode node,int targetSum,int sum) {
sum += node.val;
if(sum == targetSum && node.left == null && node.right == null)return true;
if(node == null)return false;
boolean left=false;
boolean right=false;
if(node.left != null) {
left = isEqual(node.left,targetSum,sum);
}
if(node.right != null) {
right = isEqual(node.right,targetSum,sum);
}
return (left || right);
}
106.从中序与后序遍历序列构造二叉树
题目链接:. - 力扣(LeetCode)
思路:思路就是模拟人工求解时的过程:
- 如果数组为空就返回空
- 取后序数组最后一个为根节点root
- 在中序数组中找到root位置idx
- 把中序数组分割为[0,x);[x+1,size)
- 后序数组去掉最后一个元素,跟中序一样分割为:[0,x);[x,size]
- 把责任推给左右孩子,让左左 右右继续这个过程
public TreeNode build(List<Integer> inOrder,List<Integer> postOrder) {
if(postOrder.size()==0)return null;
int treenode = postOrder.get(postOrder.size()-1);
TreeNode node = new TreeNode(treenode);
if(postOrder.size() == 1) return node;
int idx = 0;
for(int i=0;i<inOrder.size();i++) {
if(inOrder.get(i)==treenode){
idx = i;
break;
}
}
//分割inOrder
List<List<Integer>> list = partition(inOrder,idx,false);
List<Integer> leftInOrder = list.get(0);
List<Integer> rightInOrder = list.get(1);
//去掉postOrder最后一个元素
postOrder.remove(postOrder.size()-1);
//分割postOrder
list = partition(postOrder,idx,true);
List<Integer> leftPostOrder = list.get(0);
List<Integer> rightPostOrder = list.get(1);
node.left = build(leftInOrder,leftPostOrder);
node.right = build(rightInOrder,rightPostOrder);
return node;
}
开辟数组浪费时间,所以用下标来表示
public TreeNode build(int[] inOrder,int inOrderBegin,int inOrderEnd,int[] postOrder,int postOrderBegin,int postOrderEnd) {
if(postOrderEnd == postOrderBegin)return null;
int treenode = postOrder[postOrderEnd-1];
TreeNode node = new TreeNode(treenode);
if(postOrderEnd - postOrderBegin == 1) return node;
int idx = 0;
for(int i=inOrderBegin;i<inOrderEnd;i++) {
if(inOrder[i]==treenode){
idx = i;
break;
}
}
//分割inOrder,左闭右开
int leftInOrderBegin = inOrderBegin;
int leftInOrderEnd = idx;
int rightInOrderBegin = idx+1;
int rightInOrderEnd = inOrderEnd;
//去掉postOrder最后一个元素
postOrderEnd--;
//分割postOrder
int leftPostOrderBegin = postOrderBegin;
int leftPostOrderEnd = postOrderBegin + idx - inOrderBegin;
int rightPostOrderBegin = leftPostOrderEnd;
int rightPostOrderEnd = postOrderEnd;
node.left = build(inOrder,leftInOrderBegin,leftInOrderEnd,postOrder,leftPostOrderBegin,leftPostOrderEnd);
node.right = build(inOrder,rightInOrderBegin,rightInOrderEnd,postOrder,rightPostOrderBegin,rightPostOrderEnd);
return node;
}