【数据结构与算法 | 力扣+二叉搜索树篇】力扣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);
    }
}
相关推荐
呼啦啦啦啦啦啦啦啦1 小时前
常见的排序算法
java·算法·排序算法
胡萝卜3.02 小时前
数据结构初阶:排序算法(一)插入排序、选择排序
数据结构·笔记·学习·算法·排序算法·学习方法
地平线开发者2 小时前
LLM 中 token 简介与 bert 实操解读
算法·自动驾驶
lyx33136967592 小时前
Pandas数据结构详解Series与DataFrame
数据结构·pandas
scx201310043 小时前
20250814 最小生成树和重构树总结
c++·算法·最小生成树·重构树
阿巴~阿巴~3 小时前
冒泡排序算法
c语言·开发语言·算法·排序算法
散1123 小时前
01数据结构-交换排序
数据结构·算法
yzx9910133 小时前
Yolov模型的演变
人工智能·算法·yolo
weixin_307779134 小时前
VS Code配置MinGW64编译SQLite3库
开发语言·数据库·c++·vscode·算法
无聊的小坏坏4 小时前
拓扑排序详解:从力扣 207 题看有向图环检测
算法·leetcode·图论·拓扑学