day22打卡
235. 二叉搜索树的最近公共祖先
- 递归法
- 时间复杂度:O(N),空间复杂度:O(N)
class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if(root->val > p->val && root->val > q->val){TreeNode* left = lowestCommonAncestor(root->left, p, q);return left;}else if(root->val < p->val && root->val < q->val){TreeNode* right = lowestCommonAncestor(root->right, p, q);return right;}else return root;}
};
- 迭代法
- 时间复杂度:O(N),空间复杂度:O(1)
class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {while(root){if(root->val > p->val && root->val > q->val){root = root->left;}else if(root->val < p->val && root->val < q->val){root = root->right;}else return root;}return NULL;}
};
701. 二叉搜索树中的插入操作
- 递归法
- 时间复杂度:O(N),空间复杂度:O(N)
class Solution {
public:TreeNode* insertIntoBST(TreeNode* root, int val) {dfs(root, val);return root;}TreeNode* dfs(TreeNode* root, int val){if(root == nullptr){root = new TreeNode(val);return root;}if(root->val > val) root->left = dfs(root->left, val);if(root->val < val) root->right = dfs(root->right, val);return root;}
};
- 迭代法
- 时间复杂度:O(N),空间复杂度:O(N)
class Solution {
public:TreeNode* insertIntoBST(TreeNode* root, int val) {if(root == nullptr) {root = new TreeNode(val);return root;}TreeNode* cur = root;TreeNode* pre = nullptr;//记录前一个节点//找到插入位置while(cur){pre = cur;if(cur->val > val) cur = cur->left;else cur = cur->right;}//判断插入左子树还是右子树if(val > pre->val) pre->right = new TreeNode(val);else pre->left = new TreeNode(val);return root;}
};
450. 删除二叉搜索树中的节点
- 递归法
- 时间复杂度:O(N),空间复杂度:O(N)
class Solution {
public:TreeNode* deleteNode(TreeNode* root, int key) {if (root == nullptr) return root; // 第一种情况:没找到删除的节点,遍历到空节点直接返回了if (root->val == key) {// 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点if (root->left == nullptr && root->right == nullptr) {///! 内存释放delete root;return nullptr;}// 第三种情况:其左孩子为空,右孩子不为空,删除节点,右孩子补位 ,返回右孩子为根节点else if (root->left == nullptr) {auto retNode = root->right;///! 内存释放delete root;return retNode;}// 第四种情况:其右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点else if (root->right == nullptr) {auto retNode = root->left;///! 内存释放delete root;return retNode;}// 第五种情况:左右孩子节点都不为空,则将删除节点的左子树放到删除节点的右子树的最左面节点的左孩子的位置// 并返回删除节点右孩子为新的根节点。else {TreeNode* cur = root->right; // 找右子树最左面的节点while(cur->left != nullptr) {cur = cur->left;}cur->left = root->left; // 把要删除的节点(root)左子树放在cur的左孩子的位置TreeNode* tmp = root; // 把root节点保存一下,下面来删除root = root->right; // 返回旧root的右孩子作为新rootdelete tmp; // 释放节点内存return root;}}if (root->val > key) root->left = deleteNode(root->left, key);if (root->val < key) root->right = deleteNode(root->right, key);return root;}
};
- 迭代法
- 时间复杂度:O(N),空间复杂度:O(1)
class Solution {
private:// 将目标节点(删除节点)的左子树放到 目标节点的右子树的最左面节点的左孩子位置上// 并返回目标节点右孩子为新的根节点TreeNode* deleteOneNode(TreeNode* target) {if (target == nullptr) return target;if (target->right == nullptr) return target->left;TreeNode* cur = target->right;while (cur->left) {cur = cur->left;}cur->left = target->left;return target->right;}
public:TreeNode* deleteNode(TreeNode* root, int key) {if (root == nullptr) return root;TreeNode* cur = root;TreeNode* pre = nullptr; // 记录cur的父节点,用来删除curwhile (cur) {if (cur->val == key) break;pre = cur;if (cur->val > key) cur = cur->left;else cur = cur->right;}if (pre == nullptr) { // 如果搜索树只有头结点return deleteOneNode(cur);}// pre 要知道是删左孩子还是右孩子if (pre->left && pre->left->val == key) {pre->left = deleteOneNode(cur);}if (pre->right && pre->right->val == key) {pre->right = deleteOneNode(cur);}return root;}
};