
Problem Statement
In this task, we are given an array of unique integers, preorder
, representing the preorder traversal sequence of nodes' values from a binary search tree (BST). The challenge requires us to determine if the sequence can represent a correct preorder traversal of a BST. Specifically, in a valid BST, for any node:
- The left subtree has nodes with values less than the node's value.
- The right subtree has nodes with values greater than the node's value.
- Both the left and right subtrees must also be binary search trees.
Given such constraints, our task is to assess if the input preorder
array meets the criteria of a legitimate preorder traversal sequence of a BST.
Examples
Example 1
Input:
preorder = [5,2,1,3,6]
Output:
true
Example 2
Input:
preorder = [5,2,6,1,3]
Output:
false
Constraints
1 <= preorder.length <= 104
1 <= preorder[i] <= 104
- All the elements of
preorder
are unique.
Approach and Intuition
Given the constraints that all elements in the preorder
array are unique, and the nature of binary search trees, we can derive the following approach based on the nature of preorder traversal (node, left, right):
- Use a stack to simulate the insertion of elements in a BST constructed using the preorder sequence.
- Starting from the first element which represents the root, push it onto the stack.
- Initialize a variable, say
lower_bound
, to track the lower permissible bound of the next node value (this helps in verifying the properties of BST during the simulation). - Traverse the array from the second element onward.
- For each element:
- If it is less than the
lower_bound
, returnfalse
as this violates the BST property. - Keep popping from the stack as long as the current element is greater than the stack’s top (indicating the end of a left subtree and the start of a right subtree), and update the
lower_bound
to the popped value. - Push the current element onto the stack.
- If it is less than the
- For each element:
- If the entire
preorder
sequence can be processed without contradiction, returntrue
.
By this, we effectively simulate the construction of the BST and check in real-time if any element violates the conditions which would make it not represent a valid binary search tree's preorder traversal sequence. This method leverages BST properties efficiently and ensures that the sequence's integrity as a preorder traversal is maintained.
Solutions
- C++
- Java
- Python
class Solution {
public:
bool isValidPreorder(vector<int>& preorder) {
int index = 0;
return validate(preorder, index, INT_MIN, INT_MAX);
}
bool validate(vector<int>& nodes, int& idx, int lower, int upper) {
if (idx == nodes.size()) {
return true;
}
int nodeVal = nodes[idx];
if (nodeVal <= lower || nodeVal >= upper) {
return false;
}
idx++;
bool validLeftSubtree = validate(nodes, idx, lower, nodeVal);
bool validRightSubtree = validate(nodes, idx, nodeVal, upper);
return validLeftSubtree || validRightSubtree;
}
};
The provided solution in C++ addresses the problem of verifying whether a given sequence represents a valid preorder traversal of a binary search tree (BST). The implementation uses a recursive helper function to validate each node in the sequence by checking it against a dynamically updated range (lower and upper bounds).
Here's an overview of the solution:
- A class
Solution
contains a public methodisValidPreorder
which initializes the process. - The
isValidPreorder
function relies on a private helper methodvalidate
, which recurses through the sequence. - The
validate
method checks if the current value falls within the valid range for a BST node given the constraints set by previously processed nodes. - The function advances the sequence using an index reference and recursively validates both the left and right subtrees, updating the ranges accordingly.
- If a node fails to meet the constraints for either subtree, the function returns
false
, otherwise, it continues until the sequence is entirely validated.
- A class
Specific conditions and updates within the recursive function ensure both the correct structure of the BST and adherence to preorder traversal rules:
- The base case checks whether the end of the sequence is reached, returning
true
in such a case. - An immediate return of
false
occurs if a node value does not lie within the expected range. - Recursions account for both left and right children, with the index progressing linearly through the preorder list, and range limits adjusting to narrow down permissible values for subsequent nodes.
- The base case checks whether the end of the sequence is reached, returning
The use of a reference to the
index
variable allows the function to keep track of the current position in the sequence across recursive calls without duplicating the list or slicing it, enhancing both space and time efficiency.
Overall, the C++ solution effectively validates a sequence against the properties of a BST in a preorder manner, utilizing recursive techniques with range validation. This ensures each node is placed correctly according to BST rules and the order of nodes strictly follows a preorder traversal.
class Solution {
public boolean isValidPreorder(int[] preorderSequence) {
int[] index = {0};
return traverse(preorderSequence, index, Integer.MIN_VALUE, Integer.MAX_VALUE);
}
public boolean traverse(int[] preorderSequence, int[] index, int lower, int upper) {
if (index[0] == preorderSequence.length) {
return true;
}
int currentValue = preorderSequence[index[0]];
if (currentValue <= lower || currentValue >= upper) {
return false;
}
index[0]++;
boolean leftTreeValid = traverse(preorderSequence, index, lower, currentValue);
boolean rightTreeValid = traverse(preorderSequence, index, currentValue, upper);
return leftTreeValid || rightTreeValid;
}
}
The provided Java solution checks if a given array represents a valid preorder traversal sequence of a binary search tree (BST). The cornerstone of the implementation is the isValidPreorder
method, which leverages a helper method traverse
to navigate recursively through the array based on predetermined BST properties.
Here's how the solution operates:
- Start by initializing an array
index
(used to track the current position in thepreorderSequence
) with its initial value set to 0. - Use the
traverse
method recursively to verify each segment of thepreorderSequence
. The traversal checks:- The current value must lie strictly between the
lower
andupper
bounds to adhere to BST properties. - The method first checks the left subtree, ensuring all values adhere to the bounds set by the current node's value. It recursively checks this condition with the updated bounds for each node in the BST's left subtree.
- Having validated the left subtree, the method proceeds to execute similar checks on the right subtree, this time using the current node's value as the new lower bound.
- The current value must lie strictly between the
- If at any point, a value in the sequence does not comply with the conditions of the BST, the function immediately returns
false
. - The
isValidPreorder
function finally returnstrue
if all nodes in the sequence meet BST conditions, andfalse
otherwise.
This approach ensures that all constraints typical of a binary search tree are systematically validated across the whole sequence, leveraging recursion for depth-first validation of each subtree. Hence, you can rapidly determine the validity of the preorder sequence with respect to BST properties.
class Solution:
def isValidPreorder(self, preorder: List[int]) -> bool:
def check_subtree(index, lower, upper):
if index[0] == len(preorder):
return True
value = preorder[index[0]]
if not lower < value < upper:
return False
index[0] += 1
left_valid = check_subtree(index, lower, value)
right_valid = check_subtree(index, value, upper)
return left_valid or right_valid
return check_subtree([0], float('-inf'), float('inf'))
The given solution focuses on verifying if a given list of integers represents a valid preorder traversal of a binary search tree (BST). The code is implemented in Python and utilizes recursion to achieve this. Here's how the provided solution addresses the problem:
- Define a nested utility function
check_subtree
, which recursively checks the validity of the subtree. It uses parametersindex
,lower
, andupper
to maintain the current index of the list and the bounds within which the current node value must lie. - If the end of the list is reached, it indicates that all elements have been processed and conformed to the BST properties, thus returning
True
. - The value of the current node is compared against the bounds. If the value does not respect the BST property (
lower < value < upper
), the function returnsFalse
. - Recursively call
check_subtree
for the left subtree, setting the upper bound to the current node's value and for the right subtree, setting the lower bound to the node’s value. - The result of the subtree checks is combined using logical OR to determine the validity of the entire tree.
Overall, the algorithm effectively utilizes recursive checks within specified bounds to verify the authenticity of a preorder sequence as that of a BST. This solution is concise and efficiently handles the validation by leveraging the properties of BST and preorder traversal rules.
No comments yet.