递归

树的高度

力扣地址

题目描述

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

示例:
给定二叉树 [3,9,20,null,null,15,7]

1
2
3
4
5
  3
/ \
9 20
/ \
15 7

返回它的最大深度 3 。

题目解答

比较简单。。dfs

1
2
3
4
5
6
7
8
9
10
11
12
13
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None

class Solution:
def maxDepth(self, root: TreeNode) -> int:
if root is None:
return 0
return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 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), maxDepth(root.right)) + 1;


}
}

平衡树

力扣地址

题目描述

给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:

一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。

示例 1:

给定二叉树 [3,9,20,null,null,15,7]

1
2
3
4
5
  3
/ \
9 20
/ \
15 7

返回 true

示例 2:

给定二叉树 [1,2,2,3,3,null,null,4,4]

          1
      / \
     2   2
    / \
   3   3
  / \
 4   4

返回 false

题目解答

用递归计算树的高度,如果返回-1代表树不平衡。即在上一题的函数中加个判断树平衡与否的条件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None

class Solution:
def isBalanced(self, root: TreeNode) -> bool:
return self.height(root) >= 0

def height(self, root: TreeNode):
if root is None:
return 0
a = self.height(root.left)
b = self.height(root.right)
if a >= 0 and b >= 0 and abs(a - b) <= 1:
return max(a, b) + 1
else:
return -1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isBalanced(TreeNode root) {
return height(root) >= 0;

}
public int height(TreeNode root){
if(root == null){
return 0;
}
int a = height(root.left);
int b = height(root.right);
if(a >= 0 && b >= 0 && Math.abs(a-b) <= 1){
return Math.max(a,b) + 1;
}
else
return -1;
}
}

二叉树的直径

力扣地址

题目描述

给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。

示例 :
给定二叉树

      1
     / \
    2   3
   / \     
  4   5    

返回 3, 它的长度是路径 [4,2,1,3] 或者 [5,2,1,3]。

题目解答

递归,返回每个节点左右节点的之树长度的最大值,最大长度应该设置为公共变量,与每个节点左右最大长度之和比较。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None

class Solution:
maxHeight = 0
def diameterOfBinaryTree(self, root: TreeNode) -> int:
if root is None:
return 0
self.dfs(root)
return self.maxHeight

def dfs(self, root: TreeNode):
if root.left is None and root.right is None:
return 0
leftHeight = 0 if root.left is None else self.dfs(root.left) + 1
rightHeight = 0 if root.right is None else self.dfs(root.right) + 1
self.maxHeight = max(self.maxHeight, leftHeight + rightHeight)
return max(leftHeight, rightHeight)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
int maxHeight = 0;
public int diameterOfBinaryTree(TreeNode root) {
if(root == null){
return 0;
}
dfs(root);
return maxHeight;
}
public int dfs(TreeNode root){
if(root.left == null && root.right == null)
return 0;
int leftHeight = root.left == null? 0:dfs(root.left)+1;
int rightHeight = root.right == null? 0:dfs(root.right)+1;
maxHeight = Math.max(maxHeight,leftHeight + rightHeight);
return Math.max(leftHeight,rightHeight);
}
}

翻转二叉树

力扣地址

题目描述

翻转一棵二叉树。

示例:

输入:

1
2
3
4
5
     4
/ \
2 7
/ \ / \
1 3 6 9

输出:

1
2
3
4
5
     4
/ \
7 2
/ \ / \
9 6 3 1

题目解答

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None

class Solution:
def invertTree(self, root: TreeNode) -> TreeNode:
self.reverse(root)
return root

def reverse(self,root:TreeNode):
if root is None:
return
a = root.right
root.right = root.left
root.left = a
self.reverse(root.left)
self.reverse(root.right)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 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 left = root.left; // 后面的操作会改变 left 指针,因此先保存下来
root.left = invertTree(root.right);
root.right = invertTree(left);
return root;
}
}

合并二叉树

力扣地址

题目描述

给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。

你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。

示例 1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
输入: 
Tree 1 Tree 2
1 2
/ \ / \
3 2 1 3
/ \ \
5 4 7
输出:
合并后的树:
3
/ \
4 5
/ \ \
5 4 7


注意: 合并必须从两个树的根节点开始。

题目解答

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None

class Solution:
def mergeTrees(self, t1: TreeNode, t2: TreeNode) -> TreeNode:
if t1 is None and t2 is None:
return None
if t1 is None:
return t2
if t2 is None:
return t1
root = TreeNode(None)
root.val = t1.val + t2.val
root.left = self.mergeTrees(t1.left, t2.left)
root.right = self.mergeTrees(t1.right, t2.right)
return root

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
if(t1 == null && t2 == null)
return null;
if(t1 == null)
return t2;
if(t2 == null)
return t1;
TreeNode root = new TreeNode();
root.val = t1.val + t2.val;
root.left = mergeTrees(t1.left, t2.left);
root.right = mergeTrees(t1.right, t2.right);
return root;


}
}

路径总和

力扣地址

题目描述

给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。

说明: 叶子节点是指没有子节点的节点。

示例:
给定如下二叉树,以及目标和 sum = 22,

          5
         / \
        4   8
       /   / \
      11  13  4
     /  \      \
    7    2      1

返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2

题目解答

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None


class Solution:
def hasPathSum(self, root: TreeNode, sum: int) -> bool:
if root is None:
return False
if root.left is None and root.right is None and root.val == sum:
return True
return self.hasPathSum(root.left, sum - root.val) or self.hasPathSum(root.right, sum - root.val)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 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 && root.val == sum) return true;
return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val);
}
}

路径总和Ⅲ

力扣地址

题目描述

给定一个二叉树,它的每个结点都存放着一个整数值。

找出路径和等于给定数值的路径总数。

路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。

二叉树不超过1000个节点,且节点数值范围是 [-1000000,1000000] 的整数。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

题目解答

这道题需要双重递归,第一层递归选择开始节点,第二层递归向下遍历求得路径。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Definition for a binary tree node.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:

def pathSum(self, root: TreeNode, sum: int) -> int:
if root is None:
return 0
valueNum = self.dfs(root,sum) + self.pathSum(root.left, sum) + self.pathSum(root.right, sum)
return valueNum

def dfs(self,root:TreeNode,sum):
if root is None:
return 0
num = 0
if root.val == sum:
num += 1
num = num + self.dfs(root.left,sum - root.val) + self.dfs(root.right,sum - root.val)
return num


1
2
3
4
5
6
7
8
9
10
11
12
13
14
public int pathSum(TreeNode root, int sum) {
if (root == null) return 0;
int ret = pathSumStartWithRoot(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum);
return ret;
}

private int pathSumStartWithRoot(TreeNode root, int sum) {
if (root == null) return 0;
int ret = 0;
if (root.val == sum) ret++;
ret += pathSumStartWithRoot(root.left, sum - root.val) + pathSumStartWithRoot(root.right, sum - root.val);
return ret;
}

另一个树的子树

力扣地址

题目描述

给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。

示例 1:
给定的树 s:

1
2
3
4
5
    3
/ \
4 5
/ \
1 2

给定的树 t:

1
2
3
  4 
/ \
1 2

返回 true,因为 t 与 s 的一个子树拥有相同的结构和节点值。

示例 2:
给定的树 s:

1
2
3
4
5
6
7
    3
/ \
4 5
/ \
1 2
/
0

给定的树 t:

1
2
3
  4
/ \
1 2

返回 false

题目解答

和上一题类似,第一层递归判断开始的节点,第二层判断路径。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Definition for a binary tree node.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def isSubtree(self, s: TreeNode, t: TreeNode) -> bool:
if s is None:
return False
return self.dfs(s, t) or self.isSubtree(s.left, t) or self.isSubtree(s.right, t)

def dfs(self, s: TreeNode, t: TreeNode):
if s is None and t is None:
return True
if s is None or t is None:
return False
if s.val != t.val:
return False
return self.dfs(s.left, t.left) and self.dfs(s.right, t.right)

1
2
3
4
5
6
7
8
9
10
11
public boolean isSubtree(TreeNode s, TreeNode t) {
if (s == null) return false;
return isSubtreeWithRoot(s, t) || isSubtree(s.left, t) || isSubtree(s.right, t);
}

private boolean isSubtreeWithRoot(TreeNode s, TreeNode t) {
if (t == null && s == null) return true;
if (t == null || s == null) return false;
if (t.val != s.val) return false;
return isSubtreeWithRoot(s.left, t.left) && isSubtreeWithRoot(s.right, t.right);
}

对称二叉树

力扣地址

题目描述

给定一个二叉树,检查它是否是镜像对称的。

例如,二叉树 [1,2,2,3,4,4,3] 是对称的。

1
2
3
4
5
    1
/ \
2 2
/ \ / \
3 4 4 3

但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:

1
2
3
4
5
  1
/ \
2 2
\ \
3 3

题目解答

可以迭代,还是直接递归吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None


class Solution:
def isSymmetric(self, root: TreeNode) -> bool:
if root is None:
return True
return self.dfs(root.left, root.right)

def dfs(self, l: TreeNode, r: TreeNode):
if l is None and r is None:
return True
if l is None or r is None:
return False
if l.val != r.val:
return False
return self.dfs(l.left, r.right) and self.dfs(l.right, r.left)


1
2
3
4
5
6
7
8
9
10
11
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
return isSymmetric(root.left, root.right);
}

private boolean isSymmetric(TreeNode t1, TreeNode t2) {
if (t1 == null && t2 == null) return true;
if (t1 == null || t2 == null) return false;
if (t1.val != t2.val) return false;
return isSymmetric(t1.left, t2.right) && isSymmetric(t1.right, t2.left);
}

二叉树的最小深度

力扣地址

题目描述

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

说明: 叶子节点是指没有子节点的节点。

示例:

给定二叉树 [3,9,20,null,null,15,7],

1
2
3
4
5
  3
/ \
9 20
/ \
15 7

返回它的最小深度 2.

题目解答

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None


class Solution:
def minDepth(self, root: TreeNode) -> int:
if root is None:
return 0
if root.left is None and root.right is None:
return 1
if root.left is None or root.right is None:
return self.minDepth(root.left if root.left is not None else root.right) + 1
return min(self.minDepth(root.left) + 1, self.minDepth(root.right) + 1)

1
2
3
4
5
6
7
public int minDepth(TreeNode root) {
if (root == null) return 0;
int left = minDepth(root.left);
int right = minDepth(root.right);
if (left == 0 || right == 0) return left + right + 1;
return Math.min(left, right) + 1;
}

左叶子之和

力扣地址

题目描述

计算给定二叉树的所有左叶子之和。

示例:

1
2
3
4
5
6
7
    3
/ \
9 20
/ \
15 7

在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None

class Solution:
def sumOfLeftLeaves(self, root: TreeNode) -> int:
if root is None:
return 0
sum = 0
if root.left is not None:
if root.left.left is None and root.left.right is None:
sum += root.left.val
return sum + self.sumOfLeftLeaves(root.left) + self.sumOfLeftLeaves(root.right)
1
2
3
4
5
6
7
8
9
10
11
public int sumOfLeftLeaves(TreeNode root) {
if (root == null) return 0;
if (isLeaf(root.left)) return root.left.val + sumOfLeftLeaves(root.right);
return sumOfLeftLeaves(root.left) + sumOfLeftLeaves(root.right);
}

private boolean isLeaf(TreeNode node){
if (node == null) return false;
return node.left == null && node.right == null;
}

最长同值路径

力扣地址

题目描述:

给定一个二叉树,找到最长的路径,这个路径中的每个节点具有相同值。 这条路径可以经过也可以不经过根节点。

注意:两个节点之间的路径长度由它们之间的边数表示。

示例 1:

输入:

          5
         / \
        4   5
       / \   \
      1   1   5

输出:

1
2

示例 2:

输入:

          1
         / \
        4   5
       / \   \
      4   4   5

输出:

1
2

注意: 给定的二叉树不超过10000个结点。 树的高度不超过1000。

题目解答

递归的返回值和要求的结果不同,需要设置一个全局变量。

递归的返回值应该是左右最大路径之一,要求的结果,与全局变量比较的是左右最大路径之和。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None

class Solution:

def longestUnivaluePath(self, root: TreeNode) -> int:
self.maxPath = 0

def dfs(root: TreeNode):
if root is None:
return 0
left = dfs(root.left)
right = dfs(root.right)
leftPath = left + 1 if root.left is not None and root.left.val == root.val else 0
rightPath = right + 1 if root.right is not None and root.right.val == root.val else 0
self.maxPath = max(self.maxPath, leftPath + rightPath)
return max(leftPath, rightPath)

dfs(root)
return self.maxPath

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private int path = 0;

public int longestUnivaluePath(TreeNode root) {
dfs(root);
return path;
}

private int dfs(TreeNode root){
if (root == null) return 0;
int left = dfs(root.left);
int right = dfs(root.right);
int leftPath = root.left != null && root.left.val == root.val ? left + 1 : 0;
int rightPath = root.right != null && root.right.val == root.val ? right + 1 : 0;
path = Math.max(path, leftPath + rightPath);
return Math.max(leftPath, rightPath);
}

打家劫舍Ⅲ

力扣地址

题目描述

在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为“根”。 除了“根”之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警。

计算在不触动警报的情况下,小偷一晚能够盗取的最高金额。

示例 1:

输入: [3,2,3,null,3,null,1]

     3
    / \
   2   3
    \   \ 
     3   1

输出: 7 
解释: 小偷一晚能够盗取的最高金额 = 3 + 3 + 1 = 7.

示例 2:

输入: [3,4,5,1,3,null,1]

     3
    / \
   4   5
  / \   \ 
 1   3   1

输出: 9
解释: 小偷一晚能够盗取的最高金额 = 4 + 5 = 9.

题目解答

关键点:判断当前节点偷与否

python 的提交会超时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None

class Solution:
def rob(self, root: TreeNode) -> int:
"""
如果偷当前节点,则左右子节点都不能偷,
如果不偷当前节点,返回左右子节点的最大值
:param root:
:return:
"""
if root is None:
return 0
# 偷当前节点
val1 = root.val
if root.left is not None:
val1 += self.rob(root.left.left) + self.rob(root.left.right)
if root.right is not None:
val1 += self.rob(root.right.left) + self.rob(root.right.right)

# 不偷当前节点
val2 = self.rob(root.left) + self.rob(root.right)

# 返回大的
return max(val1, val2)
1
2
3
4
5
6
7
8
public int rob(TreeNode root) {
if (root == null) return 0;
int val1 = root.val;
if (root.left != null) val1 += rob(root.left.left) + rob(root.left.right);
if (root.right != null) val1 += rob(root.right.left) + rob(root.right.right);
int val2 = rob(root.left) + rob(root.right);
return Math.max(val1, val2);
}

二叉树中第二小的节点

力扣地址

题目描述

给定一个非空特殊的二叉树,每个节点都是正数,并且每个节点的子节点数量只能为 2 或 0。如果一个节点有两个子节点的话,那么该节点的值等于两个子节点中较小的一个。

给出这样的一个二叉树,你需要输出所有节点中的第二小的值。如果第二小的值不存在的话,输出 -1 。

示例 1:

1
2
3
4
5
6
7
8
9
输入: 
2
/ \
2 5
/ \
5 7

输出: 5
说明: 最小的值是 2 ,第二小的值是 5 。

示例 2:

1
2
3
4
5
6
7
输入: 
2
/ \
2 2

输出: -1
说明: 最小的值是 2, 但是不存在第二小的值。

题目解答

用python的简单方法就是用set,因为set是取不重复值,在排序后取第二个值….

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None

class Solution:
def findSecondMinimumValue(self, root: TreeNode) -> int:
if root is None:
return -1
if root.left is None and root.right is None:
return -1
# 不与根节点相同的值肯定比根节点大
# 需要比较与根节点相同值子树的值
leftVal = root.left.val
rightVal = root.right.val
if root.val == root.left.val:
leftVal = self.findSecondMinimumValue(root.left)
if root.val == root.right.val:
rightVal = self.findSecondMinimumValue(root.right)
# 取小的
if leftVal != -1 and rightVal != -1:
return min(leftVal, rightVal)
if leftVal == -1:
return rightVal
return leftVal
1
2
3
4
5
6
7
8
9
10
11
public int findSecondMinimumValue(TreeNode root) {
if (root == null) return -1;
if (root.left == null && root.right == null) return -1;
int leftVal = root.left.val;
int rightVal = root.right.val;
if (leftVal == root.val) leftVal = findSecondMinimumValue(root.left);
if (rightVal == root.val) rightVal = findSecondMinimumValue(root.right);
if (leftVal != -1 && rightVal != -1) return Math.min(leftVal, rightVal);
if (leftVal != -1) return leftVal;
return rightVal;
}

层次遍历

二叉树的层次遍历参考小浩算法)!

二叉树的层平均值

力扣地址

题目描述

给定一个非空二叉树, 返回一个由每层节点平均值组成的数组。

示例 1:

1
2
3
4
5
6
7
8
9
输入:
3
/ \
9 20
/ \
15 7
输出:[3, 14.5, 11]
解释:
第 0 层的平均值是 3 , 第1层是 14.5 , 第2层是 11 。因此返回 [3, 14.5, 11] 。

题目解答

采用队列的方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# Definition for a binary tree node.
import queue
from typing import List


class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None


class Solution:
def averageOfLevels(self, root: TreeNode) -> List[float]:
treeQueue = queue.Queue()
ave = []
if root is None:
return 0
treeQueue.put(root)
while treeQueue.qsize() > 0:
getNode = []
while treeQueue.qsize() > 0:
node = treeQueue.get()
print(node.val)
getNode.append(node)
average = 0
for i in getNode:
average += i.val
if i.left is not None:
treeQueue.put(i.left)
if i.right is not None:
treeQueue.put(i.right)
average = average / len(getNode)
ave.append(average)
return ave
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public List<Double> averageOfLevels(TreeNode root) {
List<Double> ret = new ArrayList<>();
if (root == null) return ret;
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
int cnt = queue.size();
double sum = 0;
for (int i = 0; i < cnt; i++) {
TreeNode node = queue.poll();
sum += node.val;
if (node.left != null) queue.add(node.left);
if (node.right != null) queue.add(node.right);
}
ret.add(sum / cnt);
}
return ret;
}

找树左下角的值

力扣地址

题目描述

给定一个二叉树,在树的最后一行找到最左边的值。

示例 1:

1
2
3
4
5
6
7
8
输入:

2
/ \
1 3

输出:
1

示例 2:

输入:

    1
   / \
  2   3
 /   / \
4   5   6
   /
  7
输出:
7

树根节点不为NULL

题目解答

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None


class Solution:
def findBottomLeftValue(self, root: TreeNode) -> int:
queue = [root]
res = []
while queue:
cur = []
nxt = []
for node in queue:
cur.append(node.val)
if node.left:
nxt.append(node.left)
if node.right:
nxt.append(node.right)
queue = nxt
return cur.pop(0)

1
2
3
4
5
6
7
8
9
10
public int findBottomLeftValue(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
root = queue.poll();
if (root.right != null) queue.add(root.right);
if (root.left != null) queue.add(root.left);
}
return root.val;
}

前中后序遍历(迭代实现)

使用栈

二叉树的前序遍历

力扣地址

题目描述

给定一个二叉树,返回它的 前序 遍历。

示例:

1
2
3
4
5
6
7
8
输入: [1,null,2,3]  
1
\
2
/
3

输出: [1,2,3]

要求:使用迭代

题目解答

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None


class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
stack = []
result = []
stack.append(root)
while len(stack) > 0:
a = stack.pop()
if not a:
continue
result.append(a.val)
# 左先出
stack.append(a.right)
stack.append(a.left)
return result
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> ret = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
if (node == null) continue;
ret.add(node.val);
stack.push(node.right); // 先右后左,保证左子树先遍历
stack.push(node.left);
}
return ret;
}

二叉树的后序遍历

力扣地址

题目描述

给定一个二叉树,返回它的 后序 遍历。

示例:

1
2
3
4
5
6
7
8
输入: [1,null,2,3]  
1
\
2
/
3

输出: [3,2,1]

题目解答

  • python:增加一个pre节点,如果pre节点是栈顶节点的子节点且pre不为空或栈顶节点没有子节点时,栈顶节点出栈,pre更新为出栈节点;否则将栈顶节点的右节点和左节点分别入栈。

  • java:前序遍历为 root -> left -> right,后序遍历为 left -> right -> root。可以修改前序遍历成为 root -> right -> left,那么这个顺序就和后序遍历正好相反。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# Definition for a binary tree node.
from typing import List


class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None


class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
stack = [root]
result = []
pre = None
while len(stack) > 0:
a = stack[-1]
# print(a.left,a.right)
print(1)
if not a:
continue
if ((pre == a.right or pre == a.left) and pre is not None) or (a.right is None and a.left is None):
stack.pop()
result.append(a.val)
pre = a
else:
if a.right is not None:
stack.append(a.right)
if a.left is not None:
stack.append(a.left)
return result
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> ret = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
if (node == null) continue;
ret.add(node.val);
stack.push(node.left);
stack.push(node.right);
}
Collections.reverse(ret);
return ret;
}

二叉树的中序遍历

力扣地址

题目描述

给定一个二叉树,返回它的中序 遍历。

示例:

1
2
3
4
5
6
7
8
输入: [1,null,2,3]
1
\
2
/
3

输出: [1,3,2]

题目解答

发现一种python中很秒的写法,如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Definition for a binary tree node.
from typing import List


class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None


class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
stack, rel = [root], []
while stack:
a = stack.pop()
if isinstance(a, TreeNode):
stack.extend([a.right, a.val, a.left])
elif isinstance(a, int):
rel.append(a)
return rel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> ret = new ArrayList<>();
if (root == null) return ret;
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
TreeNode node = stack.pop();
ret.add(node.val);
cur = node.right;
}
return ret;
}

二叉查找树

二叉查找树(BST):根节点大于等于左子树所有节点,小于等于右子树所有节点。

二叉查找树中序遍历有序。

修建二叉查找树

力扣地址

题目描述

给定一个二叉搜索树,同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L) 。你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。

示例 1:

1
2
3
4
5
6
7
8
9
10
11
12
输入: 
1
/ \
0 2

L = 1
R = 2

输出:
1
\
2

示例 2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
输入: 
3
/ \
0 4
\
2
/
1

L = 1
R = 3

输出:
3
/
2
/
1


题目解答

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None


class Solution:
def trimBST(self, root: TreeNode, L: int, R: int) -> TreeNode:
if not root:
return root
if root.val < L: # 左边比root更小
return self.trimBST(root.right, L, R)
if root.val > R:
return self.trimBST(root.left, L, R)

root.left = self.trimBST(root.left, L, R)
root.right = self.trimBST(root.right, L, R)
return root

1
2
3
4
5
6
7
8
public TreeNode trimBST(TreeNode root, int L, int R) {
if (root == null) return null;
if (root.val > R) return trimBST(root.left, L, R);
if (root.val < L) return trimBST(root.right, L, R);
root.left = trimBST(root.left, L, R);
root.right = trimBST(root.right, L, R);
return root;
}

二叉查找树中第k小的元素

力扣地址

题目描述

给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。

说明:
你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数。

示例 1:

1
2
3
4
5
6
7
输入: root = [3,1,4,null,2], k = 1
3
/ \
1 4
\
2
输出: 1

示例 2:

1
2
3
4
5
6
7
8
9
输入: root = [5,3,6,2,4,null,null,1], k = 3
5
/ \
3 6
/ \
2 4
/
1
输出: 3

题目解答

二叉查找树的中序遍历是有序的,返回中序编列后的第k个元素即可。

优化是提前终止。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Definition for a binary tree node.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right


class Solution:
def kthSmallest(self, root: TreeNode, k: int) -> int:
stack, rel = [root], []
while stack:
a = stack.pop()
if isinstance(a, TreeNode):
stack.extend([a.right, a.val, a.left])
elif isinstance(a, int):
rel.append(a)
return rel[k - 1]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private int cnt = 0;
private int val;

public int kthSmallest(TreeNode root, int k) {
inOrder(root, k);
return val;
}

private void inOrder(TreeNode node, int k) {
if (node == null) return;
inOrder(node.left, k);
cnt++;
if (cnt == k) {
val = node.val;
return;
}
inOrder(node.right, k);
}

把二叉搜索树转换为累加树

力扣地址

题目描述

给定一个二叉搜索树(Binary Search Tree),把它转换成为累加树(Greater Tree),使得每个节点的值是原来的节点值加上所有大于它的节点值之和。

例如:

1
2
3
4
5
6
7
8
9
输入: 原始二叉搜索树:
5
/ \
2 13

输出: 转换为累加树:
18
/ \
20 13

题目解答

先便利右子树,再遍历左子树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None


class Solution:
def convertBST(self, root: TreeNode) -> TreeNode:
cur = 0

def dfs(root: TreeNode):
if not root:
return
nonlocal cur
dfs(root.right)
cur += root.val
root.val = cur
dfs(root.left)

dfs(root)
return root

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private int sum = 0;

public TreeNode convertBST(TreeNode root) {
traver(root);
return root;
}

private void traver(TreeNode node) {
if (node == null) return;
traver(node.right);
sum += node.val;
node.val = sum;
traver(node.left);
}

二叉树搜索树的最近公共祖先

力扣地址

题目描述

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]

img

示例 1:

1
2
3
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6。

示例 2:

1
2
3
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。

说明:

  • 所有节点的值都是唯一的。
  • p、q 为不同节点且均存在于给定的二叉搜索树中。

题目解答

利用二叉搜索树的性质,如果p,q在当前节点同一侧,继续往下递归,如果在两侧,则返回当前节点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None

class Solution:
def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
if root.val > p.val and root.val > q.val:
return self.lowestCommonAncestor(root.left, p, q)
if root.val < p.val and root.val < q.val:
return self.lowestCommonAncestor(root.right, p, q)
return root

1
2
3
4
5
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root.val > p.val && root.val > q.val) return lowestCommonAncestor(root.left, p, q);
if (root.val < p.val && root.val < q.val) return lowestCommonAncestor(root.right, p, q);
return root;
}

二叉树的最近公共祖先

力扣地址

题目描述

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]

img

示例 1:

1
2
3
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出: 3
解释: 节点 5 和节点 1 的最近公共祖先是节点 3。

示例 2:

1
2
3
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出: 5
解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。

题目解答

如果搜到就p或者q就返回,如果左右都搜到就返回当前节点,如果左没有,就返回由,同理右没有就返回左。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None


class Solution:
def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
if not root or root == p or root == q:
return root
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
if left and right:
return root
if not left:
return right
return left
1
2
3
4
5
6
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q) return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
return left == null ? right : right == null ? left : root;
}

将有序数组转换为二叉搜索树

力扣地址

题目描述

将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。

本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

示例:

给定有序数组: [-10,-3,0,5,9],

一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树:

1
2
3
4
5
     0
/ \
-3 9
/ /
-10 5

题目解答

二叉搜索树的中序遍历是升序的,因此我们可以利用任一节点为根节点,数组左边为其左子树,右边为其右子树;因为题目要求高度平衡,所以选数组中间的为根节点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Definition for a binary tree node.
from typing import List


class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None


class Solution:
def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
root = self.dfs(nums, 0, len(nums) - 1)
return root

def dfs(self, nums, start, last):
if start > last:
return
mid = (start + last) // 2
root = TreeNode(nums[mid])
root.left = self.dfs(nums, start, mid - 1)
root.right = self.dfs(nums, mid + 1, last)
return root

1
2
3
4
5
6
7
8
9
10
11
12
public TreeNode sortedArrayToBST(int[] nums) {
return toBST(nums, 0, nums.length - 1);
}

private TreeNode toBST(int[] nums, int sIdx, int eIdx){
if (sIdx > eIdx) return null;
int mIdx = (sIdx + eIdx) / 2;
TreeNode root = new TreeNode(nums[mIdx]);
root.left = toBST(nums, sIdx, mIdx - 1);
root.right = toBST(nums, mIdx + 1, eIdx);
return root;
}

有序链表转换二叉搜索树

力扣地址

题目描述

给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。

本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

示例:

1
2
3
4
5
6
7
8
9
给定的有序链表: [-10, -3, 0, 5, 9],

一个可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树:

0
/ \
-3 9
/ /
-10 5

题目解答

与上一题类似,只是链表不能直接根据索引获取中间值,可以使用快慢指针。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# Definition for singly-linked list.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next


# Definition for a binary tree node.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right


class Solution:
def sortedListToBST(self, head: ListNode) -> TreeNode:

root = self.dfs(head, None)
return root

def dfs(self, head, tails):
if head == tails:
return
node = self.findMid(head, tails)
root = TreeNode(node.val)
root.left = self.dfs(head, node)
root.right = self.dfs(node.next, tails)
return root

def findMid(self, head, tails):
slow, fast = head
while fast != tails and fast.next != tails:
slow = slow.next
fast = fast.next.next
return slow
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public TreeNode sortedListToBST(ListNode head) {
if (head == null) return null;
if (head.next == null) return new TreeNode(head.val);
ListNode preMid = preMid(head);
ListNode mid = preMid.next;
preMid.next = null; // 断开链表
TreeNode t = new TreeNode(mid.val);
t.left = sortedListToBST(head);
t.right = sortedListToBST(mid.next);
return t;
}

private ListNode preMid(ListNode head) {
ListNode slow = head, fast = head.next;
ListNode pre = head;
while (fast != null && fast.next != null) {
pre = slow;
slow = slow.next;
fast = fast.next.next;
}
return pre;
}

两数之和Ⅳ

力扣地址

题目描述

给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true。

案例 1:

1
2
3
4
5
6
7
8
9
10
输入: 
5
/ \
3 6
/ \ \
2 4 7

Target = 9

输出: True

案例 2:

1
2
3
4
5
6
7
8
9
10
输入: 
5
/ \
3 6
/ \ \
2 4 7

Target = 28

输出: False

题目解答

利用中序遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None


class Solution:
def findTarget(self, root: TreeNode, k: int) -> bool:
list = []

def mid(root: TreeNode):
if root.left:
mid(root.left)
list.append(root.val)
if root.right:
mid(root.right)

mid(root)
for i in list:
if k - i == i:
continue
elif (k - i) in list:
return True
return False
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public boolean findTarget(TreeNode root, int k) {
List<Integer> nums = new ArrayList<>();
inOrder(root, nums);
int i = 0, j = nums.size() - 1;
while (i < j) {
int sum = nums.get(i) + nums.get(j);
if (sum == k) return true;
if (sum < k) i++;
else j--;
}
return false;
}

private void inOrder(TreeNode root, List<Integer> nums) {
if (root == null) return;
inOrder(root.left, nums);
nums.add(root.val);
inOrder(root.right, nums);
}

二叉搜索树的最小绝对差

力扣地址

题目描述

给你一棵所有节点为非负值的二叉搜索树,请你计算树中任意两节点的差的绝对值的最小值。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
输入:

1
\
3
/
2

输出:
1

解释:
最小绝对差为 1,其中 2 和 1 的差的绝对值为 1(或者 2 和 3)。

题目解答

利用二叉搜索树的中序遍历有序性,计算相邻元素间的差的最小值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None

class Solution:
def getMinimumDifference(self, root: TreeNode) -> int:
list = []
def mid(root: TreeNode):
if root.left:
mid(root.left)
list.append(root.val)
if root.right:
mid(root.right)
mid(root)
min = 1000000
i = 0
j = 1
while j < len(list):
if (list[j]-list[i]) < min:
min = list[j] - list[i]
j += 1
i += 1
return min
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private int minDiff = Integer.MAX_VALUE;
private TreeNode preNode = null;

public int getMinimumDifference(TreeNode root) {
inOrder(root);
return minDiff;
}

private void inOrder(TreeNode node) {
if (node == null) return;
inOrder(node.left);
if (preNode != null) minDiff = Math.min(minDiff, node.val - preNode.val);
preNode = node;
inOrder(node.right);
}

二叉搜索树中的众数

力扣地址

题目描述

给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。

假定 BST 有如下定义:

  • 结点左子树中所含结点的值小于等于当前结点的值
  • 结点右子树中所含结点的值大于等于当前结点的值
  • 左子树和右子树都是二叉搜索树

例如:
给定 BST [1,null,2,2],

1
2
3
4
5
1
\
2
/
2

返回[2].

提示:如果众数超过1个,不需考虑输出顺序

题目解答

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# Definition for a binary tree node.
from typing import List


class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None


class Solution:
def findMode(self, root: TreeNode) -> List[int]:
if not root:
return []
stack = [root]
dic = {} # 字典
while stack:
node = stack.pop()
if node.val not in dic:
dic[node.val] = 1
else:
dic[node.val] += 1
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)

max_values = max(dic.values())
list = []
for k, v in dic.items():
if v == max_values:
list.append(k)
return list
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
private int curCnt = 1;
private int maxCnt = 1;
private TreeNode preNode = null;

public int[] findMode(TreeNode root) {
List<Integer> maxCntNums = new ArrayList<>();
inOrder(root, maxCntNums);
int[] ret = new int[maxCntNums.size()];
int idx = 0;
for (int num : maxCntNums) {
ret[idx++] = num;
}
return ret;
}

private void inOrder(TreeNode node, List<Integer> nums) {
if (node == null) return;
inOrder(node.left, nums);
if (preNode != null) {
if (preNode.val == node.val) curCnt++;
else curCnt = 1;
}
if (curCnt > maxCnt) {
maxCnt = curCnt;
nums.clear();
nums.add(node.val);
} else if (curCnt == maxCnt) {
nums.add(node.val);
}
preNode = node;
inOrder(node.right, nums);
}