第一题是最大二叉树https://leetcode.cn/problems/maximum-binary-tree/,利用前序遍历,先寻找数组中最大元素作为中间根节点,接着分割左右,依次递归。
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
TreeNode* node = new TreeNode(0);
if (nums.size() == 1) {
node->val = nums[0];
return node;
}
int maxValue = 0;
int index = 0;
for(int i = 0; i < nums.size(); i++){
if (nums[i] > maxValue) {maxValue = nums[i];
index = i;
}
}
node->val = maxValue;
//分割构造左子树
if (index > 0){
vector<int> lefttree(nums.begin(), nums.begin() + index);
node->left = constructMaximumBinaryTree(lefttree);
}
//分割构造右子树
if (index < (nums.size() - 1)){
vector<int> righttree(nums.begin() + index + 1, nums.end());
node->right = constructMaximumBinaryTree(righttree);
}
return node;
}
};
将建立新数组改为处理下标过程:
class Solution {
public:
TreeNode* travel(vector<int>& nums, int left, int right){
if (left >= right) return nullptr;
int maxvalueIndex = left;
for(int i = left + 1; i < right; ++i){
if (nums[i] > nums[maxvalueIndex]) maxvalueIndex = i;
}
TreeNode* root = new TreeNode(nums[maxvalueIndex]);
//分割
root->left = travel(nums, left, maxvalueIndex);
root->right = travel(nums, maxvalueIndex + 1, right);
return root;
}
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
return travel(nums, 0, nums.size());
}
};
第二题是合并二叉树https://leetcode.cn/problems/merge-two-binary-trees/description/,知识盲区,看看卡哥思路代码随想录。发现是较简单的遍历,前序如下:
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;
}
};
层序遍历的迭代法如下:
class Solution {
public:
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
if (root1 == NULL)
return root2;
if (root2 == NULL)
return root1;
queue<TreeNode*> que;
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 != NULL && node2->left != NULL) {
que.push(node1->left);
que.push(node2->left);
} //对应左结点都有值
if (node1->right != NULL && node2->right != NULL) {
que.push(node1->right);
que.push(node2->right);
} //对应右结点都有值
if (node1->left == NULL && node2->left != NULL) {
node1->left = node2->left;
}
if (node1->right == NULL && node2->right != NULL) {
node1->right = node2->right;
}
}
return root1;
}
};
第三题是进行二叉搜索树的搜索https://leetcode.cn/problems/search-in-a-binary-search-tree/,不算难题。递归轻松拿下。
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
if(root == NULL || 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;
}
};
看了卡哥讲解,发现迭代法也很简单
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
while(root != NULL){
if (val > root->val) root = root->right;
else if (val < root->val) root = root->left;
else return root;
}
return NULL;
}
};
最后一题是验证二叉搜索树https://leetcode.cn/problems/validate-binary-search-tree/,没啥好想法,直接上卡哥的解析了代码随想录。主要思路就在于二叉搜索树的中序遍历结果是有序的。
基础解法就是将二叉搜索树的中序遍历结果转化为一个数组。
class Solution {
public:
vector<int> vec;
void travel(TreeNode* root) {
if (root == NULL) return;
travel(root->left);
vec.push_back(root->val);
travel(root->right);
}
bool isValidBST(TreeNode* root) {
vec.clear();
travel(root);
for(int i = 1; i < vec.size(); i++){
if(vec[i] <= vec[i - 1]) return false;
}
return true;
}
};
下面是不用数组的代码,用两个指针判断大小,更简洁有效。
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;
}
};
最近可能要出去旅游,断更几天😄