目录
114.二叉树展开为链表
112.路径总和
129.求根节点到叶节点数字之和
124.二叉树中的最大路径和
题意:
给你二叉树的根结点
root
,请你将它展开为一个单链表:
- 展开后的单链表应该同样使用
TreeNode
,其中right
子指针指向链表中下一个结点,而左子指针始终为null
。- 展开后的单链表应该与二叉树 先序遍历 顺序相同。
【输入样例】
root=[1,2,5,3,4,6]
【输出样例】[1,null,2,null,3,null,4,null,5,null,6]
解题思路:
先序遍历的顺序是:根 左右,
使用链表先存储先序遍历的节点顺序,之后遍历链表,更新每个节点的左右指针。
class Solution {
public void flatten(TreeNode root) {
List list = new ArrayList();
preOrder(root,list);
//list中存储的所有节点信息,已知第一个是root
int size = list.size();
for(int i=1;i list){
if(root != null){
//先遍历根节点
list.add(root);
//遍历左子树
preOrder(root.left,list);
preOrder(root.right,list);
}
}
}
时间: 击败了21.30%
内存: 击败了92.42%
解题思路2:
边遍历边展开,每一次都把右子树接到左子树的最右边节点,然后把当前节点的左子树插入到右子树上。
class Solution {
public void flatten(TreeNode root) {
while(root != null){
if(root.left == null){
//左子树为空则遍历右子树第一个节点
root = root.right;
}else{
//找到左子树最右边的节点
TreeNode prev = root.left;
while(prev.right != null){
prev = prev.right;
}
//原来的右子树接驾到这里来
prev.right = root.right;
//左子树插入到右子树
root.right = root.left;
root.left = null;//左子树一定要修改为空
//考虑下一个节点
root = root.right;
}
}
}
}
时间: 击败了100.00%
内存: 击败了62.48%
题意:
给你二叉树的根节点
root
和一个表示目标和的整数targetSum
。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和targetSum
。如果存在,返回true
;否则,返回false
。叶子节点 是指没有子节点的节点。
【输入样例】
root=[5,4,8,11,null,13,4,7,2,null,null,null,null,1],targetSum=22
【输出样例】true
解题思路:
使用深度遍历结合递归的方法
没遍历到一个节点,targetSum-=root.val;之后进行判断
1.如果targetSum=0,并且当前节点是叶子节点,返回true;
2.否则,继续遍历,遍历采用双路遍历,直接判断其继续往左子树或右子树遍历,能否找到正确的路径。
class Solution {
public int num=0;
public boolean hasPathSum(TreeNode root, int targetSum) {
if(root == null){
return false;
}
targetSum -= root.val;
if(targetSum == 0 && root.left==null && root.right==null){
return true;
}else{
return hasPathSum(root.left,targetSum) || hasPathSum(root.right,targetSum);
}
}
}
时间: 击败了100.00%
内存: 击败了45.57%
题意:
给你一个二叉树的根节点
root
,树中每个节点都存放有一个0
到9
之间的数字。每条从根节点到叶节点的路径都代表一个数字:
- 例如,从根节点到叶节点的路径
1 -> 2 -> 3
表示数字123
。计算从根节点到叶节点生成的 所有数字之和 。
叶节点 是指没有子节点的节点。
【输入样例】
root=[4,9,0,5,1]
【输出样例】1026
495+191+40=1026
解题思路:
1. 采用深度遍历的想法,首先要遍历出每一条路径,并且统计她们的数字各自是多少,之后进行相加就可以。
class Solution {
public int sumNumbers(TreeNode root) {
return depthOrder(root,0);
}
public int depthOrder(TreeNode root,int temp){
if(root == null){
return 0;
}
int sum = temp * 10 + root.val;//之前得到的和*10加上当前的数字,就是路径上的数字
if(root.left == null && root.right == null){
return sum;
}
//左子树右子树继续遍历
return depthOrder(root.left,sum)+depthOrder(root.right,sum);
}
}
时间: 击败了100.00%
内存: 击败了70.62%
题意:
二叉树中的 路径 被定义为一条节点序列,序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。
路径和 是路径中各节点值的总和。
给你一个二叉树的根节点
root
,返回其 最大路径和
【输入样例】
root=[-10,9,20,null,null,15,7]
【输出样例】42
15+20+7=42
解题思路:
实际上就是找到,在以该节点为根节点的子树中寻找以该节点为起点的一条路径,使得该路径上的节点值之和最大。
class Solution {
int maxSum = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
maxGain(root);//计算
return maxSum;
}
public int maxGain(TreeNode node){
if(node == null){
return 0;
}
//递归,计算该节点左节点的最大贡献值
//跟0比是考虑,如果这个以左节点为根,其子树所有的路径加起来都是负数,就不选择,用0代替
int leftGain = Math.max(maxGain(node.left),0);
//递归,计算该节点右节点的最大贡献值
int rightGain = Math.max(maxGain(node.right),0);
int newPathSum = node.val + leftGain + rightGain;
maxSum = Math.max(maxSum,newPathSum);
//这个return是用来递归的时候使用的,所以主函数中返回的是maxSum
return node.val + Math.max(leftGain,rightGain);
}
}
时间: 击败了100.00%
内存: 击败了47.52%