提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
654.最大二叉树
- 题目链接:654. 最大二叉树 - 力扣(LeetCode)
- 讲解链接:代码随想录
- 状态:一遍AC。
思路与重点
- 我的解法:和之前用后序和中序构造二叉树的解法一样。
class Solution {
public:TreeNode* traversal(vector<int>& nums, int L, int R){if(L > R) return nullptr;int maxIdx = L;for(int i = L + 1; i <= R; i++){if(nums[i] > nums[maxIdx]) maxIdx = i;}TreeNode* root = new TreeNode(nums[maxIdx]);root->left = traversal(nums, L, maxIdx - 1);root->right = traversal(nums, maxIdx + 1, R);return root;}TreeNode* constructMaximumBinaryTree(vector<int>& nums) {return traversal(nums, 0, nums.size() - 1);}
};
617.合并二叉树
- 题目链接:617. 合并二叉树 - 力扣(LeetCode)
- 讲解链接:代码随想录
- 状态:一遍AC。
思路与重点
- 如何同时遍历两个二叉树呢?其实和遍历一个树逻辑是一样的,只不过传入两个树的节点,同时操作。
class Solution {
public:TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {if (t1 == NULL) return t2; // 如果t1为空,合并之后就应该是t2if (t2 == NULL) return t1; // 如果t2为空,合并之后就应该是t1// 修改了t1的数值和结构t1->val += t2->val; // 中t1->left = mergeTrees(t1->left, t2->left); // 左t1->right = mergeTrees(t1->right, t2->right); // 右return t1;}
};
700.二叉搜索树中的搜索
- 题目链接:700. 二叉搜索树中的搜索 - 力扣(LeetCode)
- 讲解链接:代码随想录
- 状态:一遍AC。
思路与重点
- 递归法
class Solution {
public:TreeNode* searchBST(TreeNode* root, int val) {if (root == NULL || root->val == val) return root;if (root->val > val) return searchBST(root->left, val);if (root->val < val) return searchBST(root->right, val);return NULL;}
};
- 迭代法:对于二叉搜索树,不需要回溯的过程,因为节点的有序性就帮我们确定了搜索的方向。
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;}
};
98.验证二叉搜索树
- 题目链接:98. 验证二叉搜索树 - 力扣(LeetCode)
- 讲解链接:代码随想录
- 状态:掉进陷阱了。
思路与重点
- 要知道中序遍历下,输出的二叉搜索树节点的数值是有序序列。有了这个特性,验证二叉搜索树,就相当于变成了判断一个序列是不是递增的了。
- 注意判断递增的时候要用小于等于,二叉搜索树中不能有重复元素。
class Solution {
private:vector<int> vec;void traversal(TreeNode* root) {if (root == NULL) return;traversal(root->left);vec.push_back(root->val); // 将二叉搜索树转换为有序数组traversal(root->right);}
public:bool isValidBST(TreeNode* root) {vec.clear(); // 不加这句在leetcode上也可以过,但最好加上traversal(root);for (int i = 1; i < vec.size(); i++) {// 注意要小于等于,搜索树里不能有相同元素if (vec[i] <= vec[i - 1]) return false;}return true;}
};
- 递归来判断的话,注意不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了,我们要比较的是左子树所有节点小于中间节点,右子树所有节点大于中间节点。
- 空节点也是二叉搜索树。
- **样例中最小节点可能是int的最小值,**如果这样使用最小的int来比较也是不行的。此时可以初始化比较元素为longlong的最小值(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;}
};
- 如果测试数据中有 longlong的最小值,怎么办?不可能再初始化一个更小的值了吧。 建议避免初始化最小值,如下方法取到最左面节点的数值来比较。
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;}
};