大家好,我是 @负雪明烛。点击右上方的「+关注」↗,优质题解不间断!
题目大意
判断二叉树中所有的节点的值是否都是相等的。
并且已知,题目给出的二叉树至少有一个节点。
解题方法
二叉树问题大多都可以用「递归」和「迭代」的方法求解。本题也是如此。
左边是 BFS,按照层进行搜索;右边是DFS,先一路走到底,然后再回头搜索。
下面让我们复习一下这两种搜索方式。
BFS
BFS使用队列,把每个还没有搜索到的点依次放入队列,然后再弹出队列的头部元素当做当前遍历点。
BFS总共有两个模板:
模板一:
如果不需要确定当前遍历到了哪一层,只需要访问完所有节点就可以时。
BFS 模板如下:
while queue 不空:
cur = queue.pop()
if cur 有效且未被访问过:
进行处理
for 节点 in cur 的所有相邻节点:
if 该节点有效:
queue.push(该节点)
模板二:
如果要确定当前遍历到了哪一层,需要知道最少移动步数时,BFS 模板如下。
这里增加了 level
表示当前遍历到二叉树中的哪一层了,也可以理解为在一个图中,现在已经走了多少步了。size
表示在当前遍历层有多少个元素,也就是队列中的元素数,我们把这些元素一次性遍历完,即把当前层的所有元素都向外走了一步。
level = 0
while 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:
return
dfs(root.left)
执行操作
dfs(root.right)
3. 后序遍历:
def dfs(root):
if not root:
return
dfs(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 = None
class Solution(object):
def isUnivalTree(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
q = collections.deque()
q.append(root)
val = root.val
while q:
node = q.popleft()
if not node:
continue
if val != node.val:
return False
q.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 = right
class Solution:
def isUnivalTree(self, root: TreeNode) -> bool:
return self.dfs(root, root.val);
def dfs(self, root, val):
if not root: return True
if root.val != val: return False
return 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 题解,都在这里了,免费拿走。