Even Odd Tree solution and explanation
9 more videos on this problem
Even Odd Tree - Leetcode 1609 - PythonNeetCodeIO · 10:00 · 14K views
even odd tree | even odd tree leetcode | leetcode 1609 | bfs level orderNaresh Gupta · 9:40 · 3K views
EVEN ODD TREE | LEETCODE 1609 | PYTHON BFS SOLUTIONCracking FAANG · 10:09 · 871 views
Leetcode | 1609. Even Odd Tree | Medium | Java [BFS Solution]Developer Docs · 11:03 · 490 views
Leetcode 1609 Even Odd TreeAlgorithmicIQ · 20:04 · 475 views
LeetCode Solutions 1609. Even Odd TreeAbrar & Software Engineering · 5:35 · 393 views
1609. Even Odd Tree (Leetcode Medium)Programming Live with Larry · 8:17 · 385 views
Even Odd Tree (Leetcode 1609)Coding Interviews · 24:28 · 284 views
Leetcode 1609 Even Odd Tree (Java)TheAnalyticGuy · 9:06 · 134 views
Leetcode 1609. Even Odd TreeUnofficial Sendoh · 8:21 · 104 views
The problem
A binary tree is named Even-Odd if it meets the following conditions:
- The root of the binary tree is at level index
0, its children are at level index1, their children are at level index2, etc. - For every even-indexed level, all nodes at the level have odd integer values in strictly increasing order (from left to right).
- For every odd-indexed level, all nodes at the level have even integer values in strictly decreasing order (from left to right).
Given the root of a binary tree, return true if the binary tree is Even-Odd, otherwise return false.
Example 1:
Input: root = [1,10,4,3,null,7,9,12,8,6,null,null,2] Output: true Explanation: The node values on each level are: Level 0: [1] Level 1: [10,4] Level 2: [3,7,9] Level 3: [12,8,6,2] Since levels 0 and 2 are all odd and increasing and levels 1 and 3 are all even and decreasing, the tree is Even-Odd.
Example 2:
Input: root = [5,4,2,3,3,7] Output: false Explanation: The node values on each level are: Level 0: [5] Level 1: [4,2] Level 2: [3,3,7] Node values in level 2 must be in strictly increasing order, so the tree is not Even-Odd.
Example 3:
Input: root = [5,9,1,3,5,7] Output: false Explanation: Node values in the level 1 should be even integers.
Constraints:
- The number of nodes in the tree is in the range
[1, 105]. 1 <= Node.val <= 106
Approach overview
Problem Overview: You are given the root of a binary tree. The tree must follow strict level rules: nodes at even-indexed levels contain odd values in strictly increasing order, while nodes at odd-indexed levels contain even values in strictly decreasing order. The task is to verify whether the entire tree satisfies these constraints.
Approach 1: Level Order Traversal (BFS) (Time: O(n), Space: O(w))
This approach uses a queue to perform level order traversal, which naturally processes nodes level by level. For each level, track the previous value seen and enforce two constraints: parity (odd vs even) and ordering (increasing or decreasing). On even levels, each value must be odd and strictly greater than the previous value. On odd levels, each value must be even and strictly smaller than the previous value. Because every node is visited exactly once and checked with constant-time comparisons, the total time complexity is O(n), where n is the number of nodes. The queue may hold up to the width of the tree, giving O(w) space complexity.
This is the most intuitive method because level constraints map directly to breadth-first traversal. If you're comfortable with Breadth-First Search on a binary tree, the implementation is straightforward.
Approach 2: Depth First Search (DFS) with Level Tracking (Time: O(n), Space: O(h))
Instead of processing nodes level by level, DFS explores the tree recursively while tracking the current depth. Maintain a structure (usually a vector or map) storing the last value seen at each level. When visiting a node, check the parity rule for that level and compare its value with the stored previous value to ensure the correct ordering. If the constraint fails, terminate early.
DFS still visits each node once, so the time complexity remains O(n). The recursion stack grows up to the height of the tree, resulting in O(h) auxiliary space. This approach works well when you prefer recursive traversal patterns common in tree problems.
Recommended for interviews: The BFS level order traversal is the expected approach. The problem explicitly defines rules per level, and BFS processes nodes exactly in that order, making the validation logic simple and readable. Showing the DFS version demonstrates deeper understanding of tree traversal patterns, but BFS is typically the cleaner interview solution.
Approach 1: Level Order Traversal (BFS)
This approach employs a breadth-first search (BFS) to traverse the binary tree level by level. We maintain a queue to keep track of the nodes at each level, examining their values to ensure compliance with the Even-Odd criteria:
- For even-indexed levels, node values should be odd and in strictly increasing order.
- For odd-indexed levels, node values should be even and in strictly decreasing order.
from collections import deque
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def isEvenOddTree(self, root: TreeNode) -> bool:
if not root:
return False
queue = deque([root])
level = 0
while queue:
level_length = len(queue)
prev = None
for _ in range(level_length):
node = queue.popleft()
# Check current node value with constraints
if level % 2 == 0:
if node.val % 2 == 0 or (prev is not None and node.val <= prev):
return False
else:
if node.val % 2 != 0 or (prev is not None and node.val >= prev):
return False
prev = node.val
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
level += 1
return Trueclass TreeNode {
constructor(val, left = null, right = null) {
this.val = val;
this.left = left;
this.right = right;
}
}
function isEvenOddTree(root) {
if (!root) return false;
let queue = [root];
let level = 0;
while (queue.length > 0) {
let levelLength = queue.length;
let prev = null;
for (let i = 0; i < levelLength; i++) {
let node = queue.shift();
if (level % 2 === 0) {
if (node.val % 2 === 0 || (prev !== null && node.val <= prev)) {
return false;
}
} else {
if (node.val % 2 !== 0 || (prev !== null && node.val >= prev)) {
return false;
}
}
prev = node.val;
if (node.left) queue.push(node.left);
if (node.right) queue.push(node.right);
}
level++;
}
return true;
}The solution employs a queue for level-order traversal. On each level, it examines the nodes' values to ensure conformity with the problem's even-odd level requirements.
Time Complexity: O(N), where N is the number of nodes, as each node is inspected once.
Space Complexity: O(M), where M is the maximum number of nodes at any level in the tree (width of the tree), due to the BFS queue.
Approach 2: Depth First Search (DFS) with Level Tracking
This approach applies a depth-first search (DFS) method, maintaining level information to confirm constraints. We use recursion to explore the tree, while an array stores the last value seen on each level to validate order constraints.
import java.util.ArrayList;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
class Solution {
public boolean isValid(TreeNode node, int level, ArrayList<Integer> lastVals) {
if (node == null) return true;
if (lastVals.size() <= level) {
lastVals.add(level % 2 == 0 ? Integer.MIN_VALUE : Integer.MAX_VALUE);
}
if ((level % 2 == 0 && (node.val % 2 == 0 || node.val <= lastVals.get(level))) ||
(level % 2 == 1 && (node.val % 2 == 1 || node.val >= lastVals.get(level)))) {
return false;
}
lastVals.set(level, node.val);
return isValid(node.left, level + 1, lastVals) && isValid(node.right, level + 1, lastVals);
}
public boolean isEvenOddTree(TreeNode root) {
ArrayList<Integer> lastVals = new ArrayList<>();
return isValid(root, 0, lastVals);
}
}#include <vector>
#include <algorithm>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
class Solution {
public:
bool isValid(TreeNode* node, int level, vector<int>& lastVals) {
if (!node) return true;
if (lastVals.size() <= level) {
lastVals.push_back(level % 2 == 0 ? INT_MIN : INT_MAX);
}
if ((level % 2 == 0 && (node->val % 2 == 0 || node->val <= lastVals[level])) ||
(level % 2 == 1 && (node->val % 2 == 1 || node->val >= lastVals[level]))) {
return false;
}
lastVals[level] = node->val;
return isValid(node->left, level + 1, lastVals) && isValid(node->right, level + 1, lastVals);
}
bool isEvenOddTree(TreeNode* root) {
vector<int> lastVals;
return isValid(root, 0, lastVals);
}
};The Java variant executes similar DFS logic, using an array to record last values per level. This aids in confirming if each level maintains the necessary order based on its index (even or odd).
Time Complexity: O(N), with N being the number of tree nodes.
Space Complexity: O(H) due to recursion and array storage.
Approach 3: BFS
BFS traverses level by level. Each level is judged by its parity. The node values at each level are either all even or all odd, and they are strictly increasing or decreasing.
The time complexity is O(n), and the space complexity is O(n), where n is the number of nodes in the binary tree.
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func isEvenOddTree(root *TreeNode) bool {
even := true
q := []*TreeNode{root}
for len(q) > 0 {
var prev int = 1e7
if even {
prev = 0
}
for n := len(q); n > 0; n-- {
root = q[0]
q = q[1:]
if even && (root.Val%2 == 0 || prev >= root.Val) {
return false
}
if !even && (root.Val%2 == 1 || prev <= root.Val) {
return false
}
prev = root.Val
if root.Left != nil {
q = append(q, root.Left)
}
if root.Right != nil {
q = append(q, root.Right)
}
}
even = !even
}
return true
}Approach 4: DFS
DFS performs a pre-order traversal of the binary tree, and similarly judges whether it meets the conditions based on the parity of the layer where the node is located. During the traversal, a hash table is used to record the node value that was most recently visited at each layer.
The time complexity is O(n), and the space complexity is O(n), where n is the number of nodes in the binary tree.
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func isEvenOddTree(root *TreeNode) bool {
d := map[int]int{}
var dfs func(*TreeNode, int) bool
dfs = func(root *TreeNode, i int) bool {
if root == nil {
return true
}
even := i%2 == 0
prev, ok := d[i]
if !ok {
if even {
prev = 0
} else {
prev = 10000000
}
}
if even && (root.Val%2 == 0 || prev >= root.Val) {
return false
}
if !even && (root.Val%2 == 1 || prev <= root.Val) {
return false
}
d[i] = root.Val
return dfs(root.Left, i+1) && dfs(root.Right, i+1)
}
return dfs(root, 0)
}Complexity comparison
| Approach | Complexity |
|---|---|
| Level Order Traversal (BFS) | Time Complexity: O(N), where N is the number of nodes, as each node is inspected once. |
| Depth First Search (DFS) with Level Tracking | Time Complexity: O(N), with N being the number of tree nodes. |
| BFS | – |
| DFS | – |
Complexity analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Level Order Traversal (BFS) | O(n) | O(w) | Best when validating constraints defined per tree level |
| DFS with Level Tracking | O(n) | O(h) | Useful when implementing recursive tree traversal patterns |
Frequently asked questions
Is Even Odd Tree easy or hard?
Even Odd Tree is rated Medium difficulty. The logic itself is straightforward once you recognize it as a level-order traversal problem, but careful handling of parity checks and strict ordering conditions is required to avoid edge-case bugs.
Even Odd Tree Python/Java solution
Python and Java solutions typically use a queue for level order traversal. For each level, initialize a previous value and verify both parity (odd/even rule) and ordering (increasing or decreasing). If any node violates the rule, return false immediately; otherwise continue until all nodes are validated.
How to solve Even Odd Tree in O(n)?
Traverse the tree once and validate level constraints while visiting nodes. Using BFS, process nodes level by level with a queue, checking that even levels contain odd values in strictly increasing order and odd levels contain even values in strictly decreasing order. Since each node is processed once, the algorithm runs in O(n) time.
What is the best approach for Even Odd Tree?
Level Order Traversal (BFS) is the most practical approach. The problem defines constraints for each level of the tree, and BFS processes nodes exactly level by level. While traversing, you track the previous value in the level and enforce parity and ordering rules. This yields O(n) time and O(w) space complexity.
Is Even Odd Tree asked at Google/Amazon/Meta?
Tree validation and level-order traversal problems frequently appear in interviews at companies like Amazon, Google, and Meta. While this exact problem may not always appear, the pattern of checking constraints during BFS traversal is a common interview theme.
What data structure is used in Even Odd Tree?
The most common implementation uses a queue to perform Breadth-First Search (BFS) on the binary tree. The queue stores nodes of the current level while enforcing ordering constraints. The DFS alternative uses recursion with an array or map to track the last value seen at each level.
What is the time complexity of Even Odd Tree?
The optimal solutions run in O(n) time because every node in the binary tree is visited exactly once. Each visit performs constant-time checks for parity and ordering. Space complexity is O(w) for BFS (tree width) or O(h) for DFS recursion depth.
