代码随想录算法训练营第十九天| 235. 二叉搜索树的最近公共祖先 701.二叉搜索树中的插入操作 450.删除二叉搜索树中的节点
235. 二叉搜索树的最近公共祖先
思路:
因为是二叉搜索树,所以公共祖先一定是位于这两个节点区间中的
问题:
为什么第一个是这两个中间的例子,就是公共祖先呢?因为是最先符合要求的,
代码:
1 TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 2 { 3 if (!root) return NULL; 4 if (root == p || root == q) return root; 5 6 TreeNode* left = NULL, * right = NULL; 7 if (root->left) left = lowestCommonAncestor(root->left, p, q); 8 if (root->right) right = lowestCommonAncestor(root->right, p, q); 9 10 if (left && right) return root; 11 else if (!left && right) return right; 12 else if (!right && left) return left; 13 else return NULL; 14 }
701.二叉搜索树中的插入操作
思路:
先找到左右两个节点,如果左节点不存在, 右-左, 如果左节点存在 右不存在,那么就 左-右
代码:
1 TreeNode* insertIntoBST(TreeNode* root, int val) { 2 TreeNode* newNode = new TreeNode(val); 3 if (!root)return newNode; 4 5 TreeNode* left = NULL, * right = NULL; 6 int leftSub = INT_MAX, rightSub = INT_MAX; 7 8 stack<TreeNode*> selected; 9 selected.push(root); 10 //找出<0最大的节点 和>0最小的节点 也就是他们差值绝对值最小的节点 11 while (!selected.empty()) 12 { 13 auto cur_ = selected.top(); selected.pop(); 14 15 int val_ = cur_->val - val; 16 if (val_ < 0 && abs(leftSub) > abs(val_)) 17 { 18 leftSub = val_; 19 left = cur_; 20 } 21 else if(val_ > 0 && abs(rightSub) > abs(val_)) 22 { 23 rightSub = val_; 24 right = cur_; 25 } 26 27 if (cur_->left) selected.push(cur_->left); 28 if (cur_->right) selected.push(cur_->right); 29 } 30 31 //现在需要判断这两个节点, 左节点的右节点,或者右节点的左节点 32 33 if (left&&right) 34 { 35 if (!left->right) left->right = newNode; 36 else if (!right->left) right->left = newNode; 37 } 38 else if (left && !right) 39 { 40 left->right = newNode; 41 } 42 else if (!left && right) 43 { 44 right->left = newNode; 45 } 46 return root; 47 }
最简单的方法,
我们只关注叶子节点,如果当前节点为空,那么 就是目标节点,如果不为空,那么就返回本节点
因为他是一路追寻,所以不会出现给其他节点赋值的情况
代码:
1 TreeNode* insertIntoBST(TreeNode* root, int val) { 2 TreeNode* newNode = new TreeNode(val); 3 if (!root)return newNode; 4 5 if (root->val < val) 6 { 7 root->right = insertIntoBST(root->right, val); 8 } 9 else 10 { 11 root->left = insertIntoBST(root->left, val); 12 } 13 return root; 14 }
450.删除二叉搜索树中的节点
思路:
找到当前节点后,删掉当前节点,不要想如果我删掉当前节点,那么它的父节点怎么办?
我直接把当前的节点设置为NULL,那么它的父节点指向的也就是NULL,所以不用着急
怎么删去有左右孩子的节点:直接把左子树所有都放到右子树的最左边,就可以了
代码:
1 TreeNode* deleteNode(TreeNode* root, int key) { 2 if (!root) return NULL; 3 4 if (root->val == key) 5 { 6 if (!root->left && !root->right) 7 { 8 return NULL; 9 } 10 if (root->left && !root->right) 11 { 12 return root->left; 13 } 14 if (!root->left && root->right) 15 { 16 return root->right; 17 } 18 if (root->right && root->left) 19 { 20 auto cur_ = root->right; 21 22 while (cur_->left != NULL) 23 { 24 cur_ = cur_->left; 25 } 26 27 cur_->left = root->left; 28 return root->right; 29 } 30 } 31 32 if (root->val > key) 33 { 34 root->left = deleteNode(root->left, key); 35 } 36 if (root->val < key) 37 { 38 root->right = deleteNode(root->right, key); 39 } 40 41 return root; 42 }