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

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

1. 题目:

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

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

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

示例 1:

复制代码
输入: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. 题解

java 复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    TreeNode root1;
    public TreeNode deleteNode(TreeNode root, int key) {
        root1 = root;
        TreeNode p = root;
        TreeNode parent = null;
        while (p != null) {
            if (p.val > key) {
                parent = p;
                p = p.left;
            } else if (p.val < key) {
                parent = p;
                p = p.right;
            } else {
                break;
            }
        }
        if (p == null) {
            return root;
        }
        if (p.left == null && p.right == null) {
            shift(parent, p, null);
        } else if (p.left != null && p.right == null) {
            shift(parent, p, p.left);
        } else if (p.left == null && p.right != null) {
            shift(parent, p, p.right);
        } else {
            TreeNode s = p.right;
            TreeNode sParent = p;
            while (s.left != null) {
                sParent = s;
                s = s.left;
            }
            if (p != sParent) {
                shift(sParent, s, s.right);
                s.right = p.right;
            }
            shift(parent, p, s);
            s.left = p.left;
        }

        return root1;
    }
    public void shift(TreeNode parent, TreeNode deleted, TreeNode child) {
        if (parent == null) {
            root1 = child;
        } else if (parent.left == deleted) {
            parent.left = child;
        } else {
            parent.right = child;
        }
    }
}

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

1. 题目:

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

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

  • 节点的左 子树

    只包含小于当前节点的数。

  • 节点的右子树只包含 大于 当前节点的数。

  • 所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

复制代码
输入:root = [2,1,3]
输出:true

示例 2:

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

提示:

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

2.思路(递归):

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

3. 题解:

java 复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isValidBST(TreeNode root) {
        return doisValidBST(root);
    }
    public boolean doisValidBST(TreeNode node) {
        // 如果是空树,直接返回
        if(node == null) {
            return true;
        }
        boolean flag = true;
        TreeNode p = null;
        // 该节点存在左子树的前提下,满足节点比左子树所有节点的最大值要大
        if ((p = node.left) != null) {
            while(p.right != null) {
                p = p.right;
            }
            flag = p.val < node.val ? true : false;
        }
        // 如果flag为false,就不必要进行下列的判断了
        if(flag){
            //在节点存在右子树的前提下,满足节点比右子树的所有节点的最小值要小
            if ((p = node.right) != null) {
            while(p.left != null) {
                p = p.left;
            }
            flag = p.val > node.val ? true : false;
        }
        }
        if(node.left == null && node.right == null) {
            return flag;
        } else if (node.left != null && node.right == null) {
            return flag==true && isValidBST(node.left);
        } else if (node.left == null && node.right != null) {
            return flag && isValidBST(node.right);
        } else {
            return flag && isValidBST(node.left) && isValidBST(node.right);
        }
    }
}

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

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

5. 题解:

java 复制代码
class Solution {
    Deque<Integer> deque = new LinkedList<>();
    public boolean isValidBST(TreeNode root) {
        midTraverse(root);
        while (!deque.isEmpty()){
            int i1 = deque.pop();
            if(deque.isEmpty()){
                return true;
            }
            int i2 = deque.peek();
            if(i2 >= i1){
                return false;
            }
        }
        return true;
    }
    private void midTraverse(TreeNode node) {
        if (node == null) {
            return;
        }
        midTraverse(node.left);
        deque.push(node.val);
        midTraverse(node.right);
    }
}
相关推荐
武昌库里写JAVA26 分钟前
SpringCloud+SpringCloudAlibaba学习笔记
java·开发语言·算法·spring·log4j
小咖拉眯37 分钟前
第十六届蓝桥杯模拟赛第二期题解—Java
java·数据结构·算法·蓝桥杯·图搜索算法
Sunyanhui140 分钟前
力扣 最长回文字串-5
算法·leetcode·职场和发展
csdn_aspnet43 分钟前
C# 程序来计算三角形的面积(Program to find area of a triangle)
算法·c#
xiangxiang-44 分钟前
目标检测,图像分割,超分辨率重建
算法·机器学习·支持向量机
一直学习永不止步1 小时前
LeetCode题练习与总结:数组中两个数的最大异或值--421
java·算法·leetcode·字典树·数组·位运算·哈希表
机器学习之心1 小时前
异常检测 | 高斯分布拟合算法异常数据检测(Matlab)
算法·数学建模·matlab·异常数据检测
Ning_.1 小时前
力扣第 66 题 “加一”
算法·leetcode
kitesxian1 小时前
Leetcode437. 路径总和 III(HOT100)
算法·深度优先
YSRM1 小时前
异或-java-leetcode
java·算法·leetcode