题目描述

🔗
image.png

解题思路

递归法

  • 确定递归函数的参数以及返回值

这里我们为什么需要返回值呢?
因为是要遍历整棵树,做修改,其实不需要返回值也可以,我们也可以完成修剪(其实就是从二叉树中移除节点)的操作。
但是有返回值,更方便,可以通过递归函数的返回值来移除节点。

  • 确定终止条件

修剪的操作并不是在终止条件上进行的,所以就是遇到空节点返回就可以了。

  • 确定单层递归的逻辑

如果该节点的值大于high,那么右子树都是大于该节点的值,所以都不满足,应该递归左孩子,进 行剪切,同理小于low递归右孩子。递归之后返回递归的值,返回给上一层。
如果该节点的在low,high区间中,那么继续递归左右孩子,并返回给上一层。
image.png

  1. public TreeNode trimBST(TreeNode root, int low, int high) {
  2. if (root == null) {
  3. return null;
  4. }
  5. // 如果大于high,说明root右边的都大于high,所以返回左边满足的,但是左边不一定全部满足,所以继续递归剪枝
  6. if (root.val > high) {
  7. TreeNode left = trimBST(root.left, low, high);
  8. return left;
  9. }
  10. // 同理
  11. if (root.val < low) {
  12. TreeNode right = trimBST(root.right, low, high);
  13. return right;
  14. }
  15. // 如果此节点妈祖[low,high]区间,左右孩子不一定满足,递归左右孩子,并接住返回值
  16. root.left = trimBST(root.left, low, high);
  17. root.right = trimBST(root.right, low, high);
  18. return root;
  19. }

迭代法

  1. // 迭代法
  2. public TreeNode trimBST(TreeNode root, int low, int high) {
  3. if (root == null) return null;
  4. // 使根节点移动到[low,high]区间中
  5. while (root != null && (root.val < low || root.val > high)) {
  6. if (root.val < low) root = root.right;
  7. else root = root.left;
  8. }
  9. // 此时处理根节点的左节点,使其在[low,high]区间中
  10. TreeNode cur = root;
  11. while (cur != null) {
  12. // 注意使用while,左节点的右节点也不满足
  13. while (cur.left != null && cur.left.val < low) {
  14. cur.left = cur.left.right;
  15. }
  16. // 此时左节点的右节点满足,但是左节点的右节点的左节点不一定满足
  17. // 所以移动到下一个节点继续判断
  18. cur = cur.left;
  19. }
  20. // 处理右节点
  21. cur = root;
  22. while (cur != null) {
  23. while (cur.right != null && cur.right.val > high) {
  24. cur.right = cur.right.left;
  25. }
  26. cur = cur.right;
  27. }
  28. return root;
  29. }