LeetCode654.最大二叉树
再写完构造二叉树的题目后,此题就较为简单,代码如下:
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
if(nums.size()==0) return nullptr;
if(nums.size()==1) return new TreeNode(nums[0]);
int maxValue = INT_MIN;
int index;
for(int i=0;i<nums.size();i++){
if(nums[i]>maxValue){
maxValue = nums[i];
index = i;
}
}
TreeNode* root = new TreeNode(maxValue);
vector<int> leftNums(nums.begin(),nums.begin()+index);
vector<int> rightNums(nums.begin()+index+1,nums.end());
root->left = constructMaximumBinaryTree(leftNums);
root->right = constructMaximumBinaryTree(rightNums);
return root;
}
};
LeetCode617.合并二叉树
里面几个比较妙的思路:
1、如果一个节点为空,则直接返回另一个节点
2、不额外开辟空间,直接在一棵树上操作
3、保证两棵树的遍历顺序相同,前序遍历比较简单
代码如下:
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;
}
};
LeetCode700.二叉搜索树中的搜索
简单的二叉搜索树的逻辑
递归法:
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
if(root==nullptr) return nullptr;
if(root->val<val){
return searchBST(root->right,val);
}
if(root->val>val){
return searchBST(root->left,val);
}
return root;
}
};
迭代法:
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
while (root != NULL) {
if (root->val > val) root = root->left;
else if (root->val < val) root = root->right;
else return root;
}
return NULL;
}
};
LeetCode98.验证二叉搜索树
一个最直白的思路就是,先按照前序遍历二叉树,二叉搜索树的前序遍历应该是递增的,由此来验证,但此时时间空间复杂度就高,其实可以在遍历二叉树的时候就判断是否为搜索树。
容易陷入的误区:搜索树应该是根节点的值要大于所有左子树的值,小于所有右子树的值,而不单单大于左节点,小于右节点
一种思路时维护目前遍历过的最大值,如果大于后面的值,则false,引用代码如下:
注:测试用例中包含了INT_MIN,所以这里要用LONG_MIN,但如果测试用例包含了LONG_MIN,这种方法就失效了。
class Solution {
public:
long long maxVal = LONG_MIN; // 因为后台测试数据中有int最小值
bool isValidBST(TreeNode* root) {
if (root == NULL) return true;
bool left = isValidBST(root->left);
// 中序遍历,验证遍历的元素是不是从小到大
if (maxVal < root->val) maxVal = root->val;
else return false;
bool right = isValidBST(root->right);
return left && right;
}
};
另一种思路是记录前一个节点的值,如果与当前节点大小关系不符合,则false,以第二种思路为例,自己手写代码如下:
class Solution {
public:
TreeNode* pre=nullptr;
bool isValidBST(TreeNode* root) {
if(root==nullptr) return true;
bool left = isValidBST(root->left);
if(pre && pre->val>=root->val) return false;
pre = root;
bool right = isValidBST(root->right);
return left && right;
}
};
也可以用迭代法,引用卡哥代码如下:
class Solution {
public:
bool isValidBST(TreeNode* root) {
stack<TreeNode*> st;
TreeNode* cur = root;
TreeNode* pre = NULL; // 记录前一个节点
while (cur != NULL || !st.empty()) {
if (cur != NULL) {
st.push(cur);
cur = cur->left; // 左
} else {
cur = st.top(); // 中
st.pop();
if (pre != NULL && cur->val <= pre->val)
return false;
pre = cur; //保存前一个访问的结点
cur = cur->right; // 右
}
}
return true;
}
};