1 最大二叉树
构造二叉树要用前序(中左右):先构建父节点然后孩子节点
利用索引对所给数组进行切割
class Solution {
//构造二叉树:前序
public:
TreeNode* traversal(vector<int>& nums,int left,int right){
if(left >= right) return nullptr;
int maxIndex = left;
for(int i = left; i < right; i++){
if(nums[i] > nums[maxIndex] ) maxIndex = i;
}
TreeNode* node = new TreeNode(nums[maxIndex]);
node->left = traversal(nums,left,maxIndex);
node->right = traversal(nums,maxIndex+1,right);
return node;
}
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
return traversal(nums,0,nums.size());
}
};
2 合并二叉树
层序遍历:同时将两棵树节点放入队列进行比较
class Solution {
public:
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
queue<TreeNode*> que;
if(root1 == nullptr) return root2;
if(root2 == nullptr) return root1;
que.push(root1);que.push(root2);
while(!que.empty()){
TreeNode* node1 = que.front(); que.pop();
TreeNode* node2 = que.front(); que.pop();
node1->val += node2->val;
if(node1->left && node2->left){
que.push(node1->left);
que.push(node2->left);
}
if(node1->right && node2->right){
que.push(node1->right);
que.push(node2->right);
}
if(!node1->left && node2->left){
node1->left = node2->left;
}
if(!node1->right && node2->right){
node1->right = node2->right;
}
}
return root1;
}
};
递归
class Solution {
public:
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
if(root1 == nullptr) return root2;
if(root2 == nullptr) return root1;
root1->val += root2->val;
root1->left = mergeTrees(root1->left,root2->left);
root1->right = mergeTrees(root1->right,root2->right);
return root1;
}
};
也还可以再重新构造一个新二叉树
class Solution {
public:
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
if(root1 == nullptr) return root2;
if(root2 == nullptr) return root1;
TreeNode* root = new TreeNode(0);
root->val =root1->val + root2->val;
root->left = mergeTrees(root1->left,root2->left);
root->right = mergeTrees(root1->right,root2->right);
return root;
}
};
3 二叉搜索树中的搜索
二叉搜索树是有序树
递归
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
if(root == nullptr || root->val == val) return root;
// if(root->val > val && root->left){
// return searchBST(root->left,val);
// }
// if(root->val < val && root->right){
// return searchBST(root->right,val);
// }
// return nullptr;
TreeNode* result = nullptr;
if(root->val > val ){ //可以不用判断root->left是否存在,如果不存在进入递归首先判断是否为空
result = searchBST(root->left,val);
}
if(root->val < val ){
result = searchBST(root->right,val);
}
return result;
}
};
迭代
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
if(root == nullptr) return root;
while(root){
if(root->val < val) root = root->right;
else if(root->val > val) root = root->left;
else return root;
}
return nullptr;
}
};
4 验证二叉搜索树
二叉搜索树中序遍历:左中右,从小到大
迭代法:利用前序遍历(双指针:一个进行遍历,一个记录前一个节点)
class Solution {
//中序:左中右,从小到大
public:
bool isValidBST(TreeNode* root) {
if(root == nullptr) return true;
stack<TreeNode*> stk;
TreeNode* cur = root;//定义一个指针进行遍历
TreeNode* pre = nullptr;
while(cur != nullptr || !stk.empty()){
if(cur!=nullptr){
stk.push(cur);
cur = cur->left;//左
}else{
//中
cur = stk.top();stk.pop();
if(pre!=nullptr && pre->val >= cur->val) return false;
pre = cur;//保存前一个节点
cur = cur->right;//右
}
}
return true;
}
};
递归
class Solution {
//中序:左中右,从小到大
//双指针:记录前一个节点
public:
TreeNode* pre = nullptr;
bool isValidBST(TreeNode* root) {
//终止条件
if(root == nullptr) return true;
//左
bool left = isValidBST(root->left);
//中
if(pre!=nullptr && pre->val >= root->val) return false;
pre = root;//记录上一个节点
//右
bool right = isValidBST(root->right);
return left && right;
}
};
或者定义一个全局变量不断更新上一个节点的值(如果测试数据中有 longlong的最小值就不合适用这种方法了,可以用双指针法)
class Solution {
//中序:左中右,从小到大
public:
long long maxV = LONG_MIN;
bool isValidBST(TreeNode* root) {
//终止条件
if(root == nullptr) return true;
//左
bool left = isValidBST(root->left);
//中
if(maxV < root->val) maxV = root->val;
else return false;
//右
bool right = isValidBST(root->right);
return left && right;
}
};
不能单纯的比较左节点小于中间节点,右节点大于中间节点
而是
左子树所有节点小于中间节点,右子树所有节点大于中间节点