235 cr to 代码随想录, 从上向下去递归遍历,第一次遇到 cur节点是数值在[p, q]区间中,那么cur就是 p和q的最近公共祖先。
用层序遍历
//层序遍历 迭代
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
queue<TreeNode*> que;
que.push(root);
while (!que.empty()) {
TreeNode* curr = que.front();
que.pop();
if (curr->val<=max(p->val, q->val) && curr->val>=min(p->val, q->val)) return curr;
if (curr->left) que.push(curr->left);
if (curr->right) que.push(curr->right);
}
return NULL;
}
};
用递归(我自己写的)
//递归
class Solution {
TreeNode* traversal(TreeNode* root, TreeNode* p, TreeNode* q) {
if (root==NULL || (root->val<=max(p->val, q->val) && root->val>=min(p->val, q->val))) return root;
TreeNode* left = traversal(root->left, p, q);
TreeNode* right = traversal(root->right, p, q);
if (!left) return right;
return left;
}
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
return traversal(root, p, q);
}
};
看了代码随想录,简化版。简化是因为并不是左右节点都要递归。
//递归简化
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (root->val>p->val && root->val>q->val) {
return lowestCommonAncestor(root->left,p,q);
}
if (root->val<p->val && root->val<q->val) {
return lowestCommonAncestor(root->right,p,q);
}
return root;
}
};
701 根据BST的规则 遍历到空节点插入就好
递归如下
//递归
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if (!root) {
TreeNode* insert_node = new TreeNode(val);
return insert_node;
}
if (val>root->val) root->right = insertIntoBST(root->right, val);
if (val<root->val) root->left = insertIntoBST(root->left, val);
return root;
}
};
迭代
//迭代
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
TreeNode* curr = root;
TreeNode* pre = NULL;
while (curr) {
if (val>curr->val) {
pre = curr;
curr = curr->right;
}
else if (val<curr->val) {
pre = curr;
curr = curr->left;
}
}
TreeNode* insert_node = new TreeNode(val);
if (root == nullptr) return insert_node;
if (val>pre->val) {
pre->right = insert_node;
}
else {
pre->left = insert_node;
}
return root;
}
};
450 很难很难 一定要耐心处理每一种情况
cr to 代码随想录 分析:
- 第一种情况:没找到删除的节点,遍历到空节点直接返回了
- 找到删除的节点
- 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
- 第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
- 第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
- 第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。
迭代法,一定要把删除单独分一个function出来写 不然太容易出错了!!!
//迭代
class Solution {
TreeNode* deleter (TreeNode* target) {
if (!target->left && !target->right) return nullptr;
if (!target->left) return target->right;
if (!target->right) return target->left;
TreeNode* tmp = target->right;
while (tmp->left) {
tmp = tmp->left;
}
tmp->left = target->left;
target = target->right;
return target;
}
public:
TreeNode* deleteNode(TreeNode* root, int key) {
TreeNode* curr = root;
TreeNode* pre=nullptr;
while (curr!=nullptr) {
if (curr->val == key) break;
pre = curr;
if (key < curr->val) curr=curr->left;
else if (key > curr->val) curr=curr->right;
}
if (curr==nullptr) return root;
if (pre == nullptr) {
root = deleter(curr);
}
else if (pre->left == curr) {
pre->left = deleter(curr);
}
else if (pre->right == curr) {
pre->right = deleter(curr);
}
return root;
}
};
递归法 我这边c++但没有删掉要删的节点 浪费内存 二刷的时候要记得删 第一遍先懂逻辑
//递归
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if (!root) return root;
if (root->val == key) {
if(!root->left && !root->right) return nullptr;
else if (!root->left) root = root->right;
else if (!root->right) root = root->left;
else {
TreeNode* delete_node = root->right;
while (delete_node->left) {
delete_node = delete_node->left;
}
delete_node->left = root->left;
root = root->right;
}
}
else if (root->val>key) root->left = deleteNode(root->left, key);
else root->right = deleteNode(root->right, key);
return root;
}
};