1.最大二叉树
题目链接/文章讲解: 代码随想录
代码:
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
// 递归出口
if(nums.size() == 0) return NULL;
// 中
int index = 0;
int maxNum = INT_MIN;
for(int i = 0;i < nums.size();i++){
if(nums[i] > maxNum){
maxNum = nums[i];
index = i;
}
}
TreeNode* root = new TreeNode(maxNum);
// 此结点为叶子结点,直接返回
if(nums.size() == 1 ) return root;
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;
}
};
思路:
这道题我用的和上条博客用中序数组和后序数组构造二叉树一样的思路。代码格式也差不多。
当然直接构造新的子数组还是效率较低的(不过我感觉很易懂),改进就是每次分隔不用定义新的数组,而是通过下标索引直接在原数组上操作。
代码:(改进版)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* traversal(vector<int>& nums,int left,int right){ // 区间左闭右开
// 递归出口
if(left == right) return NULL;
// 中
int index = 0;
int maxNum = INT_MIN;
for(int i = left;i < right;i++){
if(nums[i] > maxNum){
maxNum = nums[i];
index = i;
}
}
TreeNode* root = new TreeNode(maxNum);
// 叶子结点
if(left + 1 == right){
return root;
}
// 左
root->left = traversal(nums,left,index);
// 右
root->right = traversal(nums,index + 1,right);
return root;
}
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
return traversal(nums,0,nums.size());
}
};
2.合并二叉树
题目链接/文章讲解: 代码随想录
class Solution {
public:
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
// 递归出口
if(root1 == NULL) return root2;
if(root2 == NULL) return root1;
// 中
root1->val = root1->val + root2->val;
// 左
root1->left = mergeTrees(root1->left,root2->left);
// 右
root1->right = mergeTrees(root1->right,root2->right);
return root1;
}
};
思路:其实困扰我的就两个点,一个是我怎么确定递归出口呢:两棵树要合并,如果遇到空结点,就返回另一棵子树的对应结点。(这样其实把两棵子树的结点都为空的情况处理了);还有我需要再创一个新的树来返回吗:不需要,直接改其中一棵树就好了。
以及同时操作两棵树,无非就是多加个参数,没什么了不起的。
3.二叉搜索树中的搜索
题目链接/文章讲解: 代码随想录
代码:(递归法)
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
// 递归出口
if(root == NULL) return NULL;
// 中
if(root->val == val) return root;
// 左
if(root->val > val){
return searchBST(root->left,val);
}
// 右
if(root->val < val){
return searchBST(root->right,val);
}
return root;
}
};
思路:这个和二分查找还有那么点相像,只不过我们找到不是mid而是子树的根节点。
代码:(迭代法)
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
if(root == NULL) return NULL;
TreeNode* cur = root;
while(cur != NULL){
if(cur->val == val) return cur;
if(cur->val > val) cur = cur->left;
else if(cur->val < val) cur = cur->right;
}
return cur;
}
};
因为不需要遍历所有结点,所以迭代法就不需要栈和堆等数据结构了。很简单移动的代码。就是我之前没有加else,导致我的cur更新后,又去进行下面的if判断,可能会操作空结点(好细节的问题啊)
4.验证二叉搜索树
题目链接/文章讲解: 代码随想录
代码:双指针法
class Solution {
public:
TreeNode* pre = NULL;
bool isValidBST(TreeNode* root) {
// 递归出口
if(root == NULL) return true;
// 左
bool left = isValidBST(root->left);
// 中
if(pre != NULL && pre->val >= root->val) return false;
pre = root;
// 右
bool right = isValidBST(root->right);
return left && right;
}
};
思路:双指针和二叉树遍历结合起来,其实不难,就是需要多练。以及,题上给的搜索树的定义是没有相等的情况的,所以前一个遍历结点的数组大于等于当前结点的数组,都要返回false