二叉樹
二叉樹(Binary Tree)是每個節點最多隻有兩個分支的樹結構,通常分支被稱爲“左子樹”或“右子樹”,二叉樹的分支具有左右次序,不能隨機顛倒。
二叉搜索樹(Binary Search Tree),也稱爲二叉查找樹,是指一棵空樹或者具有下列性質的二叉樹:
-
若任意節點的左子樹不空,則左子樹上所有節點的值均小於它的根節點的值;
-
若任意節點的右子樹不空,則右子樹上所有節點的值均大於它的根節點的值;
-
任意節點的左、右子樹也分別爲二搜索樹;
-
沒有鍵值相等的節點。
98. 驗證二叉搜索樹
題目描述
給定一個二叉樹,判斷其是否是一個有效的二叉搜索樹。
思路:
二叉搜索樹的中序遍歷得到有序的升序數組,基於此進行判斷是否是二叉樹。
代碼:
/**
* 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) {
stack<TreeNode*> S;
int tmp= INT_MIN;
int first = 0; //記錄,升序數組第一個值有可能爲INT_MIN
while(!S.empty() || root){
while(root){
S.push(root);
root = root->left;
}
root = S.top();
S.pop();
if(first&&root->val <= tmp){
return false;
}
first++;
tmp = root->val;
root = root->right;
}
return true;
}
};
654. 最大二叉樹
題目描述:
給定一個不含重複元素的整數數組。一個以此數組構建的最大二叉樹定義如下:
-
二叉樹的根是數組中的最大元素。
-
左子樹是通過數組中最大值左邊部分構造出的最大二叉樹。
-
右子樹是通過數組中最大值右邊部分構造出的最大二叉樹。
通過給定的數組構建最大二叉樹,並且輸出這個樹的根節點。
示例:
輸入:[3,2,1,6,0,5]
輸出:返回下面這棵樹的根節點:[6 3 5 null 2 0 null null 1]
提示:
給定的數組的大小在 [1, 1000] 之間.
思路:
遞歸,找出數組最大值所在位置然後分成兩部分
代碼:
/**
* 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:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
return MaximumBinaryTree(nums, 0, nums.size());
}
TreeNode* MaximumBinaryTree(vector<int>& nums, int begin, int end)
{
if(begin >= end){
return NULL;
}
int index = get_max_index(nums, begin, end);
TreeNode* root = new TreeNode(nums[index]);
root->left = MaximumBinaryTree(nums, begin, index);
root->right= MaximumBinaryTree(nums, index+1, end);
return root;
}
int get_max_index(vector<int>&nums, int l, int r){
int max_num = INT_MIN;
int index = -1;
for(int i=l;i<r;i++){
if(max_num<nums[i])
{
max_num = nums[i];
index = i;
}
}
return index;
}
};
96. 不同的二叉搜索樹
題目描述:
給定一個整數,求以1…n爲節點組成的二叉搜索樹有多少種?
示例:
輸入:3
輸出:5
思路:
-
首先假設第i個結點作爲根節點時,有f(x)個二叉搜索樹。那麼n個結點組成的二叉搜索樹的總個數爲G(x) = f(1) + f(2) + … + f(n)。
-
當i爲根節點時,其左子樹有i-1個根節點,右子樹則有n-i個根節點,則f(i) = G(i-1)*G(n-i)。
-
那麼:G(n)=G(0)*G(n-1)+G(1)*G(n-2)+…+G(n-1)*G(0)。G(0)=G(1)=1。
代碼:
class Solution {
public:
int numTrees(int n) {
if(n==1){
return 1;
}
vector<int> G(n+1, 0);
G[0] = 1;
G[1] = 1;
for(int i=2;i<=n;i++){
for(int j=0;j<i;j++)
{
G[i] += G[j] *G[i-j-1];
}
}
return G[n];
}
};