# 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 isValidSequence(self, root: TreeNode, arr: List[int]) -> bool:
def dfs(node, idx):
if not node or idx >= len(arr) or node.val != arr[idx]:
return False
if not node.left and not node.right and idx == len(arr) - 1:
return True
return dfs(node.left, idx + 1) or dfs(node.right, idx + 1)
return dfs(root, 0)
// 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 isValidSequence(TreeNode* root, vector<int>& arr) {
return dfs(root, arr, 0);
}
bool dfs(TreeNode* node, vector<int>& arr, int idx) {
if (!node || idx >= arr.size() || node->val != arr[idx])
return false;
if (!node->left && !node->right && idx == arr.size() - 1)
return true;
return dfs(node->left, arr, idx + 1) || dfs(node->right, arr, idx + 1);
}
};
// Definition for a binary tree node.
// public class TreeNode {
// int val;
// TreeNode left;
// TreeNode right;
// TreeNode(int x) { val = x; }
// }
class Solution {
public boolean isValidSequence(TreeNode root, int[] arr) {
return dfs(root, arr, 0);
}
private boolean dfs(TreeNode node, int[] arr, int idx) {
if (node == null || idx >= arr.length || node.val != arr[idx])
return false;
if (node.left == null && node.right == null && idx == arr.length - 1)
return true;
return dfs(node.left, arr, idx + 1) || dfs(node.right, arr, idx + 1);
}
}
/**
* 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)
* }
*/
/**
* @param {TreeNode} root
* @param {number[]} arr
* @return {boolean}
*/
var isValidSequence = function(root, arr) {
function dfs(node, idx) {
if (!node || idx >= arr.length || node.val !== arr[idx])
return false;
if (!node.left && !node.right && idx === arr.length - 1)
return true;
return dfs(node.left, idx + 1) || dfs(node.right, idx + 1);
}
return dfs(root, 0);
};
You are given the root of a binary tree and an array of integers arr
. Your task is to determine if there exists a root-to-leaf path in the tree such that the sequence of node values along this path exactly matches the given array arr
.
arr
must correspond to the value of a node along the path from the root down to a leaf.true
if there is such a path, false
otherwise.Constraints: Each node and array element is an integer. The tree and array are both non-empty.
To solve this problem, we need to check whether the given array arr
can be matched exactly by following a path from the root of the tree to one of its leaves. This suggests a recursive approach: at each node, we check if the value matches the current element in arr
, and if so, we move to the next element and the next node (either left or right).
The brute-force way would be to try every path from root to leaf and compare it to arr
. However, this is unnecessary: we can prune any path as soon as we find a mismatch. This leads to a depth-first search (DFS) approach, where we only continue down paths that still match the array so far.
We also need to ensure that the path ends exactly at a leaf and that we've used all elements of arr
by the time we reach the leaf.
dfs
) that takes the current node and the current index in arr
as parameters.
arr[idx]
, return false
.idx
is at the last element of arr
, return true
.dfs
on the left and right children with idx + 1
.true
, propagate true
up the call stack.
Suppose the tree is:
0 / \ 1 0 /| \ 0 1 0 / \ 0 1And
arr = [0,1,0,1]
.
arr[0] = 0
(match).arr[1] = 1
(match).arr[2] = 0
(no match), so backtrack.arr[2] = 0
(match).arr[3] = 1
(match).arr
, so return true
.
The function would return true
for this input.
arr
in O(L) time (L = length of arr
).
arr
, so the time complexity is O(N), where N is the number of nodes in the tree. Each recursive call processes one node and one index in arr
.
This problem is elegantly solved using a recursive depth-first search. By matching node values to the array as we traverse from root to leaf, and pruning paths as soon as a mismatch occurs, we ensure efficiency. The approach is both intuitive and optimal for this type of path-matching problem in binary trees, and leverages the natural structure of the tree and recursion.