大家好,我是 @负雪明烛。点击右上方的「+关注」↗,优质题解不间断!
题目大意
判断二叉树中所有的节点的值是否都是相等的。
并且已知,题目给出的二叉树至少有一个节点。
解题方法
二叉树问题大多都可以用「递归」和「迭代」的方法求解。本题也是如此。
左边是 BFS,按照层进行搜索;右边是DFS,先一路走到底,然后再回头搜索。

下面让我们复习一下这两种搜索方式。
BFS
BFS使用队列,把每个还没有搜索到的点依次放入队列,然后再弹出队列的头部元素当做当前遍历点。
BFS总共有两个模板:
模板一:
如果不需要确定当前遍历到了哪一层,只需要访问完所有节点就可以时。
BFS 模板如下:
while queue 不空:cur = queue.pop()if cur 有效且未被访问过:进行处理for 节点 in cur 的所有相邻节点:if 该节点有效:queue.push(该节点)
模板二:
如果要确定当前遍历到了哪一层,需要知道最少移动步数时,BFS 模板如下。
这里增加了 level 表示当前遍历到二叉树中的哪一层了,也可以理解为在一个图中,现在已经走了多少步了。size 表示在当前遍历层有多少个元素,也就是队列中的元素数,我们把这些元素一次性遍历完,即把当前层的所有元素都向外走了一步。
level = 0while queue 不空:size = queue.size()while (size --) {cur = queue.pop()if cur 有效且未被访问过:进行处理for 节点 in cur的所有相邻节点:if 该节点有效:queue.push(该节点)}level ++;
上面两个是通用模板,在任何题目中都可以用,是要理解并且记住的!
DFS
分享二叉树遍历的模板:先序、中序、后序遍历方式的区别在于把「执行操作」放在两个递归函数的位置。
伪代码在下面。
1. 先序遍历:
def dfs(root):if not root:return执行操作dfs(root.left)dfs(root.right)
2. 中序遍历:
def dfs(root):if not root:returndfs(root.left)执行操作dfs(root.right)
3. 后序遍历:
def dfs(root):if not root:returndfs(root.left)dfs(root.right)执行操作
代码
本题要判断二叉树的所有节点值是否是相同的,并且至少有一个节点。
我们把题目变成:判断所有节点的值是否都等于根节点。
如果使用 BFS,可以使用模板一,因为我们只需要把所有的节点访问一边就行了,不需要知道当前遍历到哪一层。
如果使用 DFS,由于题目没限制我们的访问次序,因此三种遍历方式都是可以的,简单来说可以使用「先序遍历」。
BFS 代码:
# Definition for a binary tree node.# class TreeNode(object):# def __init__(self, x):# self.val = x# self.left = None# self.right = Noneclass Solution(object):def isUnivalTree(self, root):""":type root: TreeNode:rtype: bool"""q = collections.deque()q.append(root)val = root.valwhile q:node = q.popleft()if not node:continueif val != node.val:return Falseq.append(node.left)q.append(node.right)return True
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/class Solution {public:bool isUnivalTree(TreeNode* root) {queue<TreeNode*> q;q.push(root);int val = root->val;while (!q.empty()) {TreeNode* node = q.front(); q.pop();if (!node) continue;if (node->val != val)return false;q.push(node->left);q.push(node->right);}return true;}};
DFS 代码:
# 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 = rightclass Solution:def isUnivalTree(self, root: TreeNode) -> bool:return self.dfs(root, root.val);def dfs(self, root, val):if not root: return Trueif root.val != val: return Falsereturn self.dfs(root.left, val) and self.dfs(root.right, val)
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/class Solution {public:bool isUnivalTree(TreeNode* root) {return dfs(root, root->val);}bool dfs(TreeNode* root, int val) {if (!root) return true;if (root->val != val) return false;return dfs(root->left, val) && dfs(root->right, val);}};
复杂度
- 时间复杂度:
,
是二叉树的节点个数。
- 空间复杂度:
,无论是
还是
都需要额外的空间。
总结
- 遇到二叉树,就 BFS 或者 DFS。
我是 @负雪明烛 ,刷算法题 1000 多道,写了 1000 多篇算法题解,收获阅读量 300 万。
关注我,你将不会错过我的精彩动画题解、面试题分享、组队刷题活动,进入主页 @负雪明烛 右侧有刷题组织,从此刷题不再孤单。
- 在刷题的时候,如果你不知道该怎么刷题,可以看 LeetCode 应该怎么刷?
- 如果你觉得题目太多,想在短时间内快速提高,可以看 LeetCode 最经典的 100 道题。
- 送你一份刷题的代码模板:【LeetCode】代码模板,刷题必会
- 我写的 1000 道 LeetCode 题解,都在这里了,免费拿走。
