# 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:
def dfs(node, value):
if not node:
return True
if node.val != value:
return False
return dfs(node.left, value) and dfs(node.right, value)
return dfs(root, root.val)
// Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
class Solution {
public:
bool isUnivalTree(TreeNode* root) {
return dfs(root, root->val);
}
private:
bool dfs(TreeNode* node, int value) {
if (!node) return true;
if (node->val != value) return false;
return dfs(node->left, value) && dfs(node->right, value);
}
};
// Definition for a binary tree node.
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
class Solution {
public boolean isUnivalTree(TreeNode root) {
return dfs(root, root.val);
}
private boolean dfs(TreeNode node, int value) {
if (node == null) return true;
if (node.val != value) return false;
return dfs(node.left, value) && dfs(node.right, value);
}
}
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
var isUnivalTree = function(root) {
function dfs(node, value) {
if (!node) return true;
if (node.val !== value) return false;
return dfs(node.left, value) && dfs(node.right, value);
}
return dfs(root, root.val);
};
You are given the root of a binary tree, represented by the variable root
. Your task is to determine whether all nodes of the tree have the same value. If every node in the tree contains the same integer value, the tree is called univalued. Return true
if the tree is univalued and false
otherwise.
To solve this problem, the first idea is to check every node in the binary tree to see if its value matches the root's value. A brute-force approach would be to traverse the entire tree and compare each node's value to the root's value.
However, we can optimize this by returning false
as soon as we find a node that does not match the root's value, which avoids unnecessary checks. We can use either depth-first search (DFS) or breadth-first search (BFS) for traversal. DFS is often simpler for recursive solutions in binary trees.
In summary, our goal is to efficiently traverse the tree and stop early if a mismatch is found, ensuring we don't waste time after the answer is already determined.
null
, return true
(since there's nothing to check).false
immediately.true
. If any mismatch is found, the recursion will bubble up false
to the top.We use recursion because it's a natural fit for tree traversal, and it allows us to check each node efficiently. The early return on mismatch ensures the algorithm is as fast as possible.
Consider the following binary tree:
1 / \ 1 1 / \ 1 1
1
.1
) — matches root.1
) — matches root.1
) — matches root.1
) — matches root.true
.
Now, if one node had value 2
instead of 1
, the recursion would return false
as soon as it encounters that node, and the final result would be false
.
O(N)
, where N
is the number of nodes in the tree.
O(N)
time.
O(log N)
; for a skewed tree, it could be O(N)
.
Both approaches have the same asymptotic time and space complexity, but the optimized approach can terminate earlier in practice.
To determine if a binary tree is univalued, we traverse the tree and compare each node's value to the root's value. By using a recursive DFS and returning early on the first mismatch, we efficiently solve the problem. This approach is elegant because it leverages the natural structure of binary trees and recursion, and it ensures we only do as much work as necessary to find the answer.