二叉树中和为某一值得路径
描述
给定一个二叉树root和一个值 sum ,判断是否有从根节点到叶子节点的节点值之和等于 sum 的路径。
1.该题路径定义为从树的根结点开始往下一直到叶子结点所经过的结点
2.叶子节点是指没有子节点的节点
3.路径只能从父节点到子节点,不能从子节点到父节点
4.总节点数目为n
例如:
给出如下的二叉树, sum=22,
解题思路:
使用递归的方法进行解决。
算法流程:
- 定义递归函数功能:判断是否当前结点root为止的路径和为sum
- 每次递归都减掉经过的结点的值
- 当前结点是叶子结点,并且sum刚好为0,表明该路径和刚好为sum
- 返回时,保证能递归每个结点,且只需要有一条路径满足即可
public class Solution {
public boolean hasPathSum(TreeNode root, int sum) {
// 递归终止条件
if (root == null)
return false;
// 每次递归都减掉经过的结点的值
sum -= root.val;
// 当前结点是叶子结点,并且sum刚好为0,表明该路径和刚好为sum
if (sum == 0 && root.left == null && root.right == null)
return true;
// 保证能递归每个结点,且只需要有一条路径满足即可
// 本质上是DFS深度优先遍历,只是由递归实现
return hasPathSum(root.left, sum) || hasPathSum(root.right, sum);
}
}
二叉搜索树与双向链表
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。如下图所示
数据范围:输入二叉树的节点数 0 \le n \le 10000≤n≤1000,二叉树中每个节点的值 0\le val \le 10000≤val≤1000
要求:空间复杂度O(1)O(1)(即在原树上操作),时间复杂度 O(n)O(n)
注意:
1.要求不能创建任何新的结点,只能调整树中结点指针的指向。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继
2.返回链表中的第一个节点的指针
3.函数返回的TreeNode,有左右指针,其实可以看成一个双向链表的数据结构
4.你不用输出双向链表,程序会根据你的返回值自动打印输出
输入描述:
二叉树的根节点
返回值描述:
双向链表的其中一个头节点。
解题思路:
使用递归的方法进行解题:
由于二叉搜索树的中序遍历是从小到大依次输出的,所以可以利用中序遍历,在遍历的过程中,逐个改变当前节点的指向。
- 预先定义一个pre指针,指向当前节点的前一个节点。以及一个head指针指向头节点。
- 当pre为空时,可以确定当前节点为双向链表的头节点head。其它情况下则可以将pre的后继指向当前节点cur。
- 遍历过程中,对于每一个cur,都应将其前驱指向pre。同时不断跟新pre。最后返回head即可。
图解展示:
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
//pre记录当前节点前一个,head记录头节点
TreeNode pre=null,head=null;
public TreeNode Convert(TreeNode pRootOfTree) {
//为空判断
if(pRootOfTree==null) return null;
//递归
dfs(pRootOfTree);
return head;
}
private void dfs(TreeNode cur){
//递归终止条件
if(cur==null) return;
//遍历左子树
dfs(cur.left);
//如果pre为空,说明当前是头节点
if(pre==null) head=cur;
//将pre的right指针指向cur
else pre.right=cur;
//将cur的left指针指向pre
cur.left=pre;
//更新pre
pre=cur;
//遍历右子树
dfs(cur.right);
}
}