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;
};