Published 2024-06-17

0098. Validate Binary Search Tree

leetcode

Problem:

We are given the root of a binary tree and our objective is to determine if it is a valid binary search tree (BST). A valid BST has the property that for every node with a value `N`, all nodes in its left subtree have values less than `N`, and all nodes in its right subtree have values greater than `N`.

To accomplish this, we can use an efficient approach leveraging DFS (Depth First Search) to traverse the tree while maintaining the constraints of the BST.

Solution Description:

To implement the validation of a BST, we need to use a recursive function that traverses the tree while keeping track of the acceptable value range for each node. Specifically, we can use the following approach:

  1. Start with the root node and an initially unbounded range (`-Infinity` to `Infinity`).
  2. For each node, check if its value lies within the current valid range.
  3. Recursively check the left subtree with an updated upper bound (the current node's value).
  4. Recursively check the right subtree with an updated lower bound (the current node's value).

Both subtrees must be valid for the entire tree to be considered a valid BST.

The time complexity of this solution is O(N), where `N` is the number of nodes, as we visit each node once. The space complexity is O(H), where `H` is the height of the tree, due to the recursion stack.

Example:

Consider the following binary tree:

``` 2 / \ 1 3 ```

The algorithm will:

  1. Check the root node with value `2` (range `-Infinity` to `Infinity`).
  2. Recursively validate the left child `1` (range `-Infinity` to `2`).
  3. Recursively validate the right child `3` (range `2` to `Infinity`).

All nodes satisfy the BST properties, so the tree is a valid BST.

Setup:

/**
 * Function to validate if a binary tree is a valid Binary Search Tree (BST).
 *
 * @param {TreeNode} root - The root node of the binary tree
 * @returns {boolean} - Returns true if the tree is a valid BST, else false
 */
function isValidBST(root) {
    // Helper definitions as instructed
    const log = typeof NestedInteger !== 'undefined' ? () => {} : console.log;
    const table = typeof NestedInteger !== 'undefined' ? () => {} : console.table;

    if (!root) return false;

    function dfs(node, low, high) {
        if (!node) return true;

        if (node.val <= low || node.val >= high) {
            return false;
        }

        return dfs(node.left, low, node.val) && dfs(node.right, node.val, high);
    }

    return dfs(root, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
}

// TreeNode structure for clarity
class TreeNode {
    constructor(val, left = null, right = null) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

// Test cases
const testCases = [
    { tree: new TreeNode(2, new TreeNode(1), new TreeNode(3)), expected: true },
    { tree: new TreeNode(5, new TreeNode(1), new TreeNode(4, new TreeNode(3), new TreeNode(6))), expected: false },
    // Add more test cases as needed
];

testCases.forEach((test, index) => {
    const result = isValidBST(test.tree);
    console.log(`Test Case ${index + 1}: ${result === test.expected ? 'Passed' : 'Failed'} (Expected: ${test.expected}, Got: ${result})`);
});
© d)zharii. sitemap