LeetCode& 剑指Offer: 二叉搜索树系列:验证二叉搜索树、二叉搜索树中的众数(利用中序遍历的方法解决)

LeetCode 98. 验证二叉搜索树

给定一个二叉树,判断其是否是一个有效的二叉搜索树。

假设一个二叉搜索树具有如下特征:

  • 节点的左子树只包含小于当前节点的数。
  • 节点的右子树只包含大于当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

输入:

    2
   /  \
  1    3

输出: true

示例 2:
输入:

 5
/ \
1   4
   / \
  3   6

输出: false
解释: 输入为: [5,1,4,null,null,3,6]。
根节点的值为 5 ,但是其右子节点值为 4 。

解题思路:中序遍历

根据二叉搜索树的特点:左结点的值<根结点的值<右结点的值。而中序遍历的结果恰好得到一个升序的序列。进行中序遍历时,判断当前节点是否大于中序遍历的前一个节点,如果大于,说明满足 BST,继续遍历;否则直接返回 false。

代码实现:
  • C++:
/**
 * 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 isValidBST(TreeNode* root) {
        long pre = LONG_MIN;
        return inorder(root,pre);
    }
    bool inorder(TreeNode* root,long &inder){
        if(root == NULL){
            return true;
        }
        if (!inorder(root->left, inder)) {
            return false;
        }
        if(root->val <= inder){
            return false;
        }
        inder = root->val;
        return inorder(root->right,inder);
    }
};
  • 利用栈来进行中序遍历:
/**
 * 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 isValidBST(TreeNode* root) {
        long pre = LONG_MIN;
        stack<TreeNode*> stack;
        while (!stack.empty() || root != nullptr) {
            while (root != nullptr) {
                stack.push(root);
                root = root -> left;
            }
            root = stack.top();
            stack.pop();
            // 如果中序遍历得到的节点的值小于等于前一个 inorder,说明不是二叉搜索树
            if (root -> val <= pre) return false;
            pre = root -> val;
            root = root -> right;
        }
        return true;
    }
};

LeetCode 501. 二叉搜索树中的众数

给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。

假定 BST 有如下定义:

  • 结点左子树中所含结点的值小于等于当前结点的值
  • 结点右子树中所含结点的值大于等于当前结点的值
  • 左子树和右子树都是二叉搜索树

例如:

给定 BST [1,null,2,2],

  1
   \
    2
   /
 2

返回[2].

提示:如果众数超过1个,不需考虑输出顺序

解题思路和上题类似,利用中序遍历的思想。
中序遍历会得到一个升序序列,逐个比对当前结点(root)值与前驱结点(pre)值。更新当前节点值出现次数(curTimes)及最大出现次数(maxTimes),更新规则:若curTimes=maxTimes,将root->val添加到结果向量(res)中;若curTimes>maxTimes,清空res,将root->val添加到res,并更新maxTimes为curTimes。

代码实现如下:

/**
 * 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:
    void inorder(TreeNode* root, TreeNode*& pre,int& curTimes, int& maxTimes,vector<int>& res){
        if (!root) return;
        inorder(root->left,pre,curTimes,maxTimes,res);
        if(pre && pre->val == root->val){
            curTimes = curTimes + 1;
        }
        else{
            curTimes = 1;
        }
        if(curTimes == maxTimes){
            res.push_back(root->val);
        }
        if(curTimes>maxTimes){
            maxTimes = curTimes;
            res.clear();
            res.push_back(root->val);
        }
        pre = root;
        inorder(root->right,pre,curTimes,maxTimes,res);
    }
    vector<int> findMode(TreeNode* root) {
        vector<int> res;
        if (!root) return res;
        TreeNode* pre = NULL;
        int curTimes = 1,maxTimes = 0;
        inorder(root,pre,curTimes,maxTimes,res);
        return res;
    }
};
  • 使用中序遍历将结点的值存到数组v中,然后将问题转化成求数组v的众数.
/**
 * 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:
    vector<int> findMode(TreeNode* root) {
        int curTimes = 1,maxTimes = 1;
        inorder(root);
        if(vec.size()==0) return res;//处理输入为空的情况
        res.push_back(vec[0]);//初始化res数组
        for(int i = 1; i < vec.size();i++){
            if(vec[i-1] == vec[i]){
                curTimes += 1;
            }
            else{
                curTimes = 1;
            }
            if(curTimes == maxTimes){
                res.push_back(vec[i]);
            }
            else if(curTimes>maxTimes){
                res.clear();
                maxTimes = curTimes;
                res.push_back(vec[i]);
            }
        }
        return res;

    }
    void inorder(TreeNode* root){
        if(!root){
            return ;
        }
        inorder(root->left);
        vec.push_back(root->val);
        inorder(root->right);
    }
private:
    vector<int> res;
    vector<int> vec;
};

你可能感兴趣的:(LeetCode,牛客网刷题,算法,leetcode,二叉搜索树,数据结构,剑指Offer)