二叉树
二叉树(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];
}
};