104. 二叉树的最大深度
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],3
/ \
9 20
/ \
15 7
返回它的最大深度 3 。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
if(root == null){
return 0;
}
return Math.max(maxDepth(root.left)+1, maxDepth(root.right)+1);
}
}
111
226. 翻转二叉树
翻转一棵二叉树。
示例:
输入:
4
/ \
2 7
/ \ / \
1 3 6 9
输出:4
/ \
7 2
/ \ / \
9 6 3 1
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null){
return null;
}
TreeNode l = invertTree(root.left);
TreeNode r = invertTree(root.right);
root.left = r;
root.right = l;
return root;
}
}
100
101
222
110
使用递归时,要注意递归终止的条件
112. 路径总和
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。说明: 叶子节点是指没有子节点的节点。
示例:
给定如下二叉树,以及目标和 sum = 22,5
/ \
4 8
/ / \
11 13 4
/ \ \
7 2 1
返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。
思路:
sum = 5 时, 在如下情况,注意递归终止条件,需要满足从根节点到叶子节点,非叶子节点求得的值不满足题意
5
\
8
/ \
13 4
/ \ \
7 2 1
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean hasPathSum(TreeNode root, int sum) {
if(root == null){
return false;
}
//叶子节点
if(root.left == null && root.right == null){
return root.val == sum;
}
if(hasPathSum(root.left, sum-root.val)){
return true;
}
if(hasPathSum(root.right, sum-root.val)){
return true;
}
return false;
}
}
111
404
递归的逻辑部分,递归逻辑部分有时候会比较复杂
257. 二叉树的所有路径
给定一个二叉树,返回所有从根节点到叶子节点的路径。
说明: 叶子节点是指没有子节点的节点。
示例:
输入:
1
/ \
2 3
\
5输出: ["1->2->5", "1->3"]
解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
List<String> l = new ArrayList<>();
if(root == null){
return l;
}
if(root.left == null && root.right == null){
l.add(root.val+"");
return l;
}
List<String> ll = binaryTreePaths(root.left);
for(String e : ll){
l.add(root.val+"->"+e);
}
List<String> rl = binaryTreePaths(root.right);
for(String e : rl){
l.add(root.val+"->"+e);
}
return l;
}
}
113
129
437. Path Sum III
给定一个二叉树,它的每个结点都存放着一个整数值。
找出路径和等于给定数值的路径总数。
路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
二叉树不超过1000个节点,且节点数值范围是 [-1000000,1000000] 的整数。
示例:
root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
10
/ \
5 -3
/ \ \
3 2 11
/ \ \
3 -2 1返回 3。和等于 8 的路径有:
1. 5 -> 3
2. 5 -> 2 -> 1
3. -3 -> 11
思路:注意该题,寻找的路径不一定是从当前节点出发,用一个额外的递归实现从当前节点出发满足条件的路径的条数,使用双重递归,递归嵌套
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int pathSum(TreeNode root, int sum) {
if(root == null){
return 0;
}
int res = Paths(root, sum);
res += pathSum(root.left, sum);
res += pathSum(root.right, sum);
return res;
}
//以当前节点为出发点,满足条件的路径数目
private int Paths(TreeNode root, int sum){
int res = 0;
if(root == null){
return 0;
}
if(root.val == sum){
res++;
}
res += Paths(root.left, sum-root.val);
res += Paths(root.right, sum-root.val);
return res;
}
}
二分搜索树相关问题
二分搜索树的基本操作:插入(insert),查找(find),删除(delete)
由于二分搜索树天生的顺序性,可以很方便的实现一些操作:
- 最大值,最小值 minimum,maximum
- 前驱,后继 succeccor,predecessor
- 上界,下界 floor,ceil
- 某个元素的排名 rank
- 寻找第k大(小)的元素 select
235. 二叉搜索树的最近公共祖先
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
示例 1:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6。示例 2:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。
说明:
所有节点的值都是唯一的。
p、q 为不同节点且均存在于给定的二叉搜索树中。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
//根据二分搜索树的性质,某个节点的左子树所有的值均小于该节点的值,而右子树所有节点的值均大于该节点的值
//递归实现
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null){
return null;
}
if(root.val>q.val && root.val>p.val){
return lowestCommonAncestor(root.left, p, q);
}
if(root.val<q.val && root.val<p.val){
return lowestCommonAncestor(root.right, p, q);
}
// 其余情况, root本身就是公共祖先
//if((root.val>=p.val && root.val<=q.val) || (root.val>=q.val && root.val<=p.val) )
return root;
}
}
98
450
108
230
236 (经典的LCA问题 Lowest Common Ancestor of a Binary Tree)