654.最大二叉树
我的版本
- 类似于从前序后序构造二叉树
- 关键点类似于二分查找
- 去寻找那个区间不变量,我用的这个算是左开右闭的区间
class Solution1 {
//每次构造新数组,占用空间大
public:
TreeNode *constructMaximumBinaryTree(vector<int> &nums) {
if (nums.size() == 0)return nullptr;
int maxIndex = 0;
int maxValue = INT_MIN;
for (int i = 0; i < nums.size(); ++i) {
if (nums[i] > maxValue) {
maxValue = nums[i];
maxIndex = i;
}
}
TreeNode *root = new TreeNode(maxValue);
vector<int> leftnums(nums.begin(), nums.begin() + maxIndex);
vector<int> rightnums(nums.begin() + maxIndex + 1, nums.end());
root->left = constructMaximumBinaryTree(leftnums);
root->right = constructMaximumBinaryTree(rightnums);
return root;
}
};
class Solution2 {
//函数参数传入左右区间索引,一直使用nums数组,提高性能
public:
TreeNode *traversal(const vector<int> &nums, int leftIndex, int rightInndex) {
if (leftIndex >= rightInndex) return nullptr;
int maxIndex = 0;
int maxValue = INT_MIN;
for (int i = leftIndex; i < rightInndex; ++i) {
if (nums[i] > maxValue) {
maxValue = nums[i];
maxIndex = i;
}
}
TreeNode *root = new TreeNode(maxValue);
int left_leftIndex = leftIndex;
int left_rightIndex = maxIndex;
int right_leftIndex = maxIndex + 1;
int right_rightIndex = rightInndex;
root->left = traversal(nums, left_leftIndex, left_rightIndex);
root->right = traversal(nums, right_leftIndex, right_rightIndex);
return root;
}
TreeNode *constructMaximumBinaryTree(vector<int> &nums) {
//还是说要注意区间,我这里用的是左闭右开
return traversal(nums, 0, nums.size());
}
};
代码随想录
意思一样
617.合并二叉树
我的版本
- 有点类似于对称二叉树,都是操作两个二叉树
- 关键点就是遍历到某一个节点时
- 如果两个树结构对不上了,直接返回有的那个子树补上来即可
- 如果两个节点都存在,直接相加就行
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;
}
};
代码随想录
- 递归方法是一样的
迭代方法
- 使用队列模拟的进行层序遍历,
class Solution {
public:
TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
if (t1 == NULL) return t2;
if (t2 == NULL) return t1;
queue<TreeNode*> que;
que.push(t1);
que.push(t2);
while(!que.empty()) {
TreeNode* node1 = que.front(); que.pop();
TreeNode* node2 = que.front(); que.pop();
// 此时两个节点一定不为空,val相加
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);
}
// 当t1的左节点 为空 t2左节点不为空,就赋值过去
if (node1->left == NULL && node2->left != NULL) {
node1->left = node2->left;
}
// 当t1的右节点 为空 t2右节点不为空,就赋值过去
if (node1->right == NULL && node2->right != NULL) {
node1->right = node2->right;
}
}
return t1;
}
};
700.二叉搜索树中的搜索
我的版本
- 直接递归,如果空就返回null
- 找到了返回当前root
- 大了的话去左子树找,小了同理
class Solution {
public:
TreeNode *searchBST(TreeNode *root, int val) {
if (root == nullptr) return nullptr;
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 nullptr;
}
};
代码随想录
多了一个迭代的方法:
- 由于是二叉搜索树,直接按照大了向左,小了向右。一直走就好了
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.验证二叉搜索树
我的版本
- 因为是二叉搜索树嘛,直接中序遍历得到的应该是一个递增数组
- 检查这个数组是不是递增的就好
class Solution {
public:
void traversal(TreeNode *root, vector<int> &nums) {
if (root == nullptr) return;
traversal(root->left, nums);
nums.push_back(root->val);
traversal(root->right, nums);
}
bool isValidBST(TreeNode *root) {
vector<int> nums;
traversal(root, nums);
int temp = nums[0];
for (auto iter = nums.begin() + 1; iter != nums.end(); ++iter) {
//注意这里是小于等于 不是小于
if (*iter <= temp)
return false;
temp = *iter;
}
return true;
}
};
代码随想录
递归
除了获得数组之外,给出了递归的方法:
- 不能淡出的比较左节点小于中间节点就行,因为左节点下面的节点可能不合法
- 要比较左子树所有节点小于中间节点,右子树所有节点大于中间节点
- 注意测试样例中有INT_MIN,所以使用一个longlong
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;
}
};
迭代
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;
}
};
day20结束