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;
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章