LeetCode - 98. Validate Binary Search Tree

问题 Medium

Given a binary tree, determine if it is a valid binary search tree (BST).

Assume a BST is defined as follows:

  • The left subtree of a node contains only nodes with keys less than the node’s key.
  • The right subtree of a node contains only nodes with keys greater than the node’s key.
  • Both the left and right subtrees must also be binary search trees.

Example 1:

    2
   / \
  1   3

Binary tree [2,1,3], return true.

Example 2:

    1
   / \
  2   3

Binary tree [1,2,3], return false.

分析

  • 刚开始我想的是使用递归,比较每个节点和它的左右孩子,后来发现这种方法不对,因为有的树,比如左孩子确实比该节点小,但是左孩子的右孩子比该节点大,这种情况就无法判断出来。
  • 后来还是使用最常规的方法,就是下面方法的第一种,因为BST的中序遍历是一个从小到大的有序数列,所以先采用简单的递归方式完成中序遍历得到数组,然后扫描一遍数组确定是否从小到大,若不是,则说明不是BST。这里面做了两次时间复杂度为O(n)的运算。
  • 下面第二种方法,不再使用递归法完成中序遍历,而是使用迭代法,这样一来就能在迭代的过程中去验证是否每一个值都比前一个值小。这样做的好处是,可能树还没有遍历完,就能发现这不是BST,且后面也不用再扫描数组,故速度快。

代码

/**
 * 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:
     //方法一:思想是判断中序遍历之后的数组如果不是有序数组,则不是BST
    vector<int> result;
    void MidOrder(TreeNode* root)
    {
        if(root)
        {
        if(root->left)  MidOrder(root->left);
        result.push_back(root->val);
        if(root->right) MidOrder(root->right);
        }
    }

    bool isOrder(vector<int> &nums)
    {
        if(nums.size() == 0) return true;
        for(int i=0; i<nums.size()-1; i++)  //需要先在前一行处理size==0的情况,不然 nums.size()-1 会出错,详见参考。
            if(nums[i] >= nums[i+1])
                return false;
        return true;
    }

    bool isValidBST(TreeNode* root) {
        if(root) MidOrder(root);
        return isOrder(result);
    }

    //方法二:上面采用递归的方式中序遍历BST,现在采用迭代的方式遍历,
    //能够直接在迭代过程中完成检查,不一定需要遍历完整棵树,所以更快。
    //这种迭代 来中序遍历树的方法能够用在很多地方。
    bool isValidBST(TreeNode* root) {
        if(root == NULL) return true;
        stack<TreeNode*> stack;
        TreeNode* previous = NULL;  //必须初始化为NULL
        while(root || !stack.empty())
        {
            while(root)
            {
                stack.push(root);
                root = root->left;
            }
            root = stack.top();
            if(previous != NULL && (previous->val >= root->val)) return false;
            previous = root;    //有人不加上面一行判断和这行赋值,直接一开始就将用来比较的值初始化为INT_MIN之类,不好
            root = root->right;
            stack.pop();
        }
        return true;
    }
};

总结

  • 1.上述第一种方法中,isOrder()函数内,在使用 i

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值