【数据结构与算法 | 力扣+二叉搜索树篇】力扣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);
    }
}
相关推荐
呃呃本2 小时前
算法题(矩阵)
线性代数·算法·矩阵
呃呃本3 小时前
算法题(普通数组、矩阵)
线性代数·算法·矩阵
计算机安禾3 小时前
【计算机网络】第11篇:链路状态路由协议——Dijkstra算法与OSPF的分区架构
计算机网络·算法·架构
珂朵莉MM3 小时前
第七届全球校园人工智能算法精英大赛-算法巅峰赛产业命题赛第二赛季优化题--遗传算法
人工智能·算法
gihigo19983 小时前
严格耦合波分析计算光栅衍射效率算法
算法
可编程芯片开发3 小时前
基于双Qlearning强化学习的温差发电系统电压动态补偿算法matlab仿真
算法·matlab·双qlearning强化学习·电压动态补偿·温差发电系统
Java成神之路-3 小时前
【LeetCode 刷题笔记】69.x 的平方根 | 二分查找经典刷题题解
算法·leetcode
灵智实验室3 小时前
PX4状态估计技术EKF2详解(一):EKF2 开篇——从分离到统一
算法·无人机·px 4
小智老师PMP3 小时前
六月PMP晚启动急救|现在开始,每天2-3小时,稳冲一次上岸(附可直接照搬计划)
算法·软件工程·求职招聘·产品经理·敏捷流程
tankeven3 小时前
动态规划专题(11):区间动态规划之三角剖分问题
c++·算法·动态规划