一、前言
参考文献:代码随想录
今天还是二叉树,二叉树真是一个很大的章节。今天刷的题目并不简单,所以我继续参考卡哥的文献了。
二、最大二叉树:
1、思路:
我一开始地思路就是分开递归,左子树写一个递归,右子树写一个递归。但是发现根本行不通,因为子树的遍历也需要同时构建出左右子树,而我的代码根本照顾不过来。这里我就不展示,思路并不好。
看了一下卡哥的视频,发现我题目都读错了。。
我总结了以下几点:
(1)构造二叉树一般使用的是前序遍历:中,左,右
(2)传入参数:nums数组;返回值:root;
(3)终止条件:当nums.size()为1时,就说明是叶子节了。返回叶子节点即可。
(4)中:找出最大值和最大值的下标。
(5)左:利用最大值的下标,进行分割;
(6)右:利用最大值的下标,进行分割;
(7)返回根节点;
2、代码如下:
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
// 终止条件,遍历到叶子节点了
if (nums.size() == 1) {
return new TreeNode(nums[0]);
}
// 找到最大值
int max = 0; // 题目中说明节点的值都大于等于0
int maxIndex;
for (int i = 0; i < nums.size(); i++) {
if (max < nums[i]) {
max = nums[i];
maxIndex = i;
}
}
TreeNode* node = new TreeNode(nums[maxIndex]);
// 左
if (maxIndex > 0) { // 左区间需要存在值
// 区间:左闭右开
vector<int> newVec(nums.begin(), nums.begin() + maxIndex);
node->left = constructMaximumBinaryTree(newVec);
}
// 右
if (maxIndex < (nums.size() - 1)) { // 右区间需要存在值
// 区间:左闭右开
vector<int> newVec(nums.begin() + maxIndex + 1, nums.end());
node->right = constructMaximumBinaryTree(newVec);
}
return node;
}
}
三、合并二叉树
1、思路:
看着题解不难,但是自己想也是想不出来呀。。
我总结了以下几点:
(1)处理两棵二叉树时,和一个二叉树的遍历差不太多;
(2)终止条件:看那棵树为空,空就返回另外一颗树;
(3)以一棵树为基准,做累加;
(4)递归左子树,右子树;
(5)采用前序遍历,中序遍历,后续遍历均可以;
2、前序代码如下:
class Solution {
public:
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
if (root1 == NULL) return root2;
if (root2 == NULL) return root1;
// 中
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* mergeTrees(TreeNode* root1, TreeNode* root2) {
if (root1 == NULL) return root2;
if (root2 == NULL) return root1;
// 左
root1->left = mergeTrees(root1->left, root2->left);
// 中
root1->val += root2->val;
// 右
root1->right = mergeTrees(root1->right, root2->right);
return root1;
}
};
四、二叉搜索树中的搜索
1、思路:
这一题只需要知道BST树的性质即可。
BST树:
比根节点大的在右边,小的在左边,就是这样。利用好这个性质就可以拿下了;
(1)首先判断root是否为空,不为空继续判断是否等于val,不等于就开始递归了;
(2)递归需要采用一个result来记录,没有记录的话,就会报错。
2、代码如下:
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
if(root == NULL) return NULL;
if (root->val == val) return root;
TreeNode* result = NULL;
if (root->val > val) result = searchBST(root->left, val);
if (root->val < val) result = searchBST(root->right, val);
return result;
}
};
五、验证二叉搜索树:
1、思路:
我一开始想的就是用递归比较两边写出了如下代码:
bool isValidBST(TreeNode* root) {
if (root->left == NULL || root->right == NULL) return true;
bool result = false;
if (root->left != NULL && root->val > root->left->val)
{
result = isValidBST(root->left);
}
if (root->right != NULL && root->val < root->right->val)
{
result = isValidBST(root->right);
}
else
{
return false;
}
return result;
}
真是愚蠢的代码。。。
像这种就不符要求要,以及[1,1]
卡哥的方法,类似于把二叉树从左->中->右遍历,检查是否按升序遍历,如果是就返回true,不是就返回false。
2、代码如下:
class Solution {
public:
// 比较变量
long long maxVal = LONG_MIN;
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;
}
};
今日学习时间:2小时;
Leave message:
My life has been full of terrible misfortunes most of which never happend.
我的生活充满了可怕的不幸,其中大部分从未发生过。