当前位置:   article > 正文

【数据结构与算法 | 力扣+二叉搜索树篇】力扣450, 98

【数据结构与算法 | 力扣+二叉搜索树篇】力扣450, 98

1. 力扣450:删除二叉搜索树的节点

1. 题目:

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

一般来说,删除节点可分为两个步骤:

  1. 首先找到需要删除的节点;
  2. 如果找到了,删除它。

示例 1:

e6a16dc3738a4e91b547ba349bea5bcd.jpeg

输入:root = [5,3,6,2,4,null,7], key = 3
输出:[5,4,6,2,null,null,7]
解释:给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。
一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。
另一个正确答案是 [5,2,6,null,4,null,7]。


示例 2:

输入: root = [5,3,6,2,4,null,7], key = 0
输出: [5,3,6,2,4,null,7]
解释: 二叉树不包含值为 0 的节点

示例 3:

输入: root = [], key = 0
输出: []

提示:

  • 节点数的范围 [0, 104].
  • -105 <= Node.val <= 105
  • 节点值唯一
  • root 是合法的二叉搜索树
  • -105 <= key <= 105

进阶: 要求算法时间复杂度为 O(h),h 为树的高度。

2. 题解

  1. /**
  2. * Definition for a binary tree node.
  3. * public class TreeNode {
  4. * int val;
  5. * TreeNode left;
  6. * TreeNode right;
  7. * TreeNode() {}
  8. * TreeNode(int val) { this.val = val; }
  9. * TreeNode(int val, TreeNode left, TreeNode right) {
  10. * this.val = val;
  11. * this.left = left;
  12. * this.right = right;
  13. * }
  14. * }
  15. */
  16. class Solution {
  17. TreeNode root1;
  18. public TreeNode deleteNode(TreeNode root, int key) {
  19. root1 = root;
  20. TreeNode p = root;
  21. TreeNode parent = null;
  22. while (p != null) {
  23. if (p.val > key) {
  24. parent = p;
  25. p = p.left;
  26. } else if (p.val < key) {
  27. parent = p;
  28. p = p.right;
  29. } else {
  30. break;
  31. }
  32. }
  33. if (p == null) {
  34. return root;
  35. }
  36. if (p.left == null && p.right == null) {
  37. shift(parent, p, null);
  38. } else if (p.left != null && p.right == null) {
  39. shift(parent, p, p.left);
  40. } else if (p.left == null && p.right != null) {
  41. shift(parent, p, p.right);
  42. } else {
  43. TreeNode s = p.right;
  44. TreeNode sParent = p;
  45. while (s.left != null) {
  46. sParent = s;
  47. s = s.left;
  48. }
  49. if (p != sParent) {
  50. shift(sParent, s, s.right);
  51. s.right = p.right;
  52. }
  53. shift(parent, p, s);
  54. s.left = p.left;
  55. }
  56. return root1;
  57. }
  58. public void shift(TreeNode parent, TreeNode deleted, TreeNode child) {
  59. if (parent == null) {
  60. root1 = child;
  61. } else if (parent.left == deleted) {
  62. parent.left = child;
  63. } else {
  64. parent.right = child;
  65. }
  66. }
  67. }

2. 力扣98 :验证二叉搜索树

1. 题目:

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

  • 节点的左

    子树

    只包含 小于 当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

a0d64713dd2c49d1b3a537973809ef35.jpeg

输入:root = [2,1,3]
输出:true

示例 2:

51b6a1398ce04a01bfe1762ca55c3571.jpeg

输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。

提示:

  • 树中节点数目范围在[1, 104] 内
  • -231 <= Node.val <= 231 - 1

2.思路(递归):

对于该题我们可以使用递归的方法去解决。由于二叉搜索树的特性,一个节点比其左孩子的值要大,比右孩子的要小(如果其有左右孩子的话),但由此条件是不够推出其是二叉搜索树的。如果某节点的值满足比其左子树的最大值要大,比其右子树的最小值要小,并且其左孩子和右孩子都满足该规则的话,是可以推出该是一个有效的二叉搜索树的。

3. 题解:

  1. /**
  2. * Definition for a binary tree node.
  3. * public class TreeNode {
  4. * int val;
  5. * TreeNode left;
  6. * TreeNode right;
  7. * TreeNode() {}
  8. * TreeNode(int val) { this.val = val; }
  9. * TreeNode(int val, TreeNode left, TreeNode right) {
  10. * this.val = val;
  11. * this.left = left;
  12. * this.right = right;
  13. * }
  14. * }
  15. */
  16. class Solution {
  17. public boolean isValidBST(TreeNode root) {
  18. return doisValidBST(root);
  19. }
  20. public boolean doisValidBST(TreeNode node) {
  21. // 如果是空树,直接返回
  22. if(node == null) {
  23. return true;
  24. }
  25. boolean flag = true;
  26. TreeNode p = null;
  27. // 该节点存在左子树的前提下,满足节点比左子树所有节点的最大值要大
  28. if ((p = node.left) != null) {
  29. while(p.right != null) {
  30. p = p.right;
  31. }
  32. flag = p.val < node.val ? true : false;
  33. }
  34. // 如果flag为false,就不必要进行下列的判断了
  35. if(flag){
  36. //在节点存在右子树的前提下,满足节点比右子树的所有节点的最小值要小
  37. if ((p = node.right) != null) {
  38. while(p.left != null) {
  39. p = p.left;
  40. }
  41. flag = p.val > node.val ? true : false;
  42. }
  43. }
  44. if(node.left == null && node.right == null) {
  45. return flag;
  46. } else if (node.left != null && node.right == null) {
  47. return flag==true && isValidBST(node.left);
  48. } else if (node.left == null && node.right != null) {
  49. return flag && isValidBST(node.right);
  50. } else {
  51. return flag && isValidBST(node.left) && isValidBST(node.right);
  52. }
  53. }
  54. }

4. 思路(有序递增数列)

由题可知,中序遍历得到的序列一定是递增数列。

5. 题解:

  1. class Solution {
  2. Deque<Integer> deque = new LinkedList<>();
  3. public boolean isValidBST(TreeNode root) {
  4. midTraverse(root);
  5. while (!deque.isEmpty()){
  6. int i1 = deque.pop();
  7. if(deque.isEmpty()){
  8. return true;
  9. }
  10. int i2 = deque.peek();
  11. if(i2 >= i1){
  12. return false;
  13. }
  14. }
  15. return true;
  16. }
  17. private void midTraverse(TreeNode node) {
  18. if (node == null) {
  19. return;
  20. }
  21. midTraverse(node.left);
  22. deque.push(node.val);
  23. midTraverse(node.right);
  24. }
  25. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/950068
推荐阅读
相关标签
  

闽ICP备14008679号