二叉树篇

class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        return sortedArrayToBST(nums, 0, nums.length);
    }
    
    public TreeNode sortedArrayToBST(int[] nums, int left, int right) {
        if (left >= right) {
            return null;
        }
        if (right - left == 1) {
            return new TreeNode(nums[left]);
        }
        int mid = left + (right - left) / 2;
        TreeNode root = new TreeNode(nums[mid]);
        root.left = sortedArrayToBST(nums, left, mid);
        root.right = sortedArrayToBST(nums, mid + 1, right);
        return root;
    }
}

二叉树篇

二叉树的遍历方式

前序遍历

image-20241127205819897

递归

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<Integer>();
        preorder(root, result);
        return result;
    }
    
    public void preorder(TreeNode root, List<Integer> result) {
        if (root == null) {
            return;
        }
        result.add(root.val);
        preorder(root.left, result);
        preorder(root.right, result);
    }
}

迭代(非递归)

/**
 * 前序遍历顺序:中-左-右,入栈顺序:中-右-左
 */
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            result.add(node.val);
            if (node.right != null) {
                stack.push(node.right);
            }
            if (node.left != null) {
                stack.push(node.left);
            }
        }
        
        return result;
    }
}

后序遍历

递归

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<postteger>();
        postorder(root, result);
        return result;
    }
    
    public void postorder(TreeNode root, List<Integer> result) {
        if (root == null) {
            return;
        }
        // 后序:左右根
        postorder(root.left, result);
        postorder(root.right, result);
        result.add(root.val);
    }
}

迭代(非递归)

/**
 * 后序遍历顺序 左-右-中 入栈顺序:中-左-右 出栈顺序:中-右-左, 最后翻转结果
 */
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            result.add(node.val);
            if (node.left != null) {
                stack.push(node.left);
            }
            if (node.right != null) {
                stack.push(node.right);
            }
        }
        // 这个地方翻转很重要
        Collections.reverse(result);
        
        return result;
    }
}

这个地方,后序是左右根,我们先得到根右左,然后再进行翻转,然后根右左,可以通过和先序一样的方法得到。

中序遍历

image-20241127210810061

递归

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<Integer>();
        inorder(root, result);
        return result;
    }
    
    public void inorder(TreeNode root, List<Integer> result) {
        if (root == null) {
            return;
        }
        // 中序:左根右
        inorder(root.left, result);
        result.add(root.val);
        inorder(root.right, result);
    }
}

迭代(非递归)

/**
 * 中序遍历顺序: 左-中-右 入栈顺序: 左-右
 */
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        while (cur != null || !stack.isEmpty()) {
            if (cur != null) {
                stack.push(cur);
                // 处理左节点
                cur = cur.left;
            } else {
                // 最左节点取出来并加入数组
                cur = stack.pop(); 
                result.add(cur.val);
                // 处理右节点
                cur = cur.right;
            }
        }
        
        return result;
    }
}

二叉树统一迭代法

以前序为例:

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new LinkedList<>();
        Stack<TreeNode> st = new Stack<>();
        if (root != null) st.push(root);
        while (!st.empty()) {
            TreeNode node = st.peek();
            if (node != null) {
                st.pop();   // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中
                if (node.right != null) {
                    st.push(node.right);    // 添加右节点(空节点不入栈)
                }
                if (node.left != null) {
                    st.push(node.left); // 添加左节点(空节点不入栈)
                }
                st.push(node);
                st.push(null);  // 中节点访问过,但是还没有处理,加入空节点做为标记。
                
            } else {    // 只有遇到空节点的时候,才将下一个节点放进结果集
                st.pop();   // 将空节点弹出
                node = st.peek();   // 重新取出栈中元素
                st.pop();
                result.add(node.val);   // 加入到结果集
            }
        }
        
        return result;
    }
}

这个做法,以前序为例,根左右。先访问根,再删除根,通过根的记录找到右子树和左子树,最后再重新访问根,达到右左根的顺序,放入栈中,出栈访问的顺序即为根左右。

层序遍历

自顶向下的层序遍历

image-20241128165300644

法二 递归
/**
 * BFS--递归方式
 */

class Solution {
    public List<List<Integer>> resList = new ArrayList<List<Integer>>();
    public List<List<Integer>> levelOrder(TreeNode root) {
        checkFun01(root, 0);
        
        return resList;
    }
    
    // BFS --递归方式
    public void checkFun01(TreeNode node, Integer deep) {
        if (node == null) return;
        deep++;
        
        // 到达新的一层时,先创建新一层的集合
        if (resList.size() < deep) {
            //当层级增加时,list的Item也增加,利用list的索引值进行层级界定
            List<Integer> item = new ArrayList<Integer>();
            resList.add(item);
        }
        resList.get(deep-1).add(node.val);
        
        checkFun01(node.left, deep);
        checkFun01(node.right, deep);
    }
}
我经常使用的方法-法一
/**
 * BFS--迭代方式--借助队列
 */
class Solution {
    public List<List<Integer>> resList = new ArrayList<List<Integer>>();
    public List<List<Integer>> levelOrder(TreeNode root) {
        checkFun02(root);
        
        return resList;
    }
    
    // BFS--迭代方式--借助队列
    public void checkFun02(TreeNode node) {
        if (node == null) return;
        Queue<TreeNode> que = new LinkedList<TreeNode>();
        que.offer(node);
        
        while (!que.isEmpty()) {
            List<Integer> itemList = new ArrayList<Integer>();
            int len = que.size();
            
            while (len > 0) {
                TreeNode tmpNode = que.poll();
                itemList.add(tmpNode.val);
                
                if (tmpNode.left != null) que.offer(tmpNode.left);
                if (tmpNode.right != null) que.offer(tmpNode.right);
                len--;
            }
            resList.add(itemList);
        }
    }
}

自底向上的层序遍历

image-20241128174723136

相当于自顶向上的层序遍历,然后将数组里面的小数组从新换个顺序即可
    
List<List<Integer>> result = new ArrayList<>();
        for (int i = list.size() - 1; i >= 0; i-- ) {
            result.add(list.get(i));
        }

二叉树的属性

对称二叉树

image-20241129094422650

/**
 * 递归法
 */

class Solution {
    public boolean isSymmetric(TreeNode root) {
        return compare(root.left, root.right);
    }
    
    private boolean compare(TreeNode left, TreeNode right) {
        if (left == null && right != null) {
            return false;
        }
        if (left != null && right == null) {
            return false;
        }
        if (left == null && right == null) {
            return true;
        }
        if (left.val != right.val) {
            return false;
        }

        // 比较外侧
        boolean compareOutside = compare(left.left, right.right);
        // 比较内侧
        boolean compareInside = compare(left.right, right.left);
        return compareOutside && compareInside;
    }
}

二叉树的最大深度

image-20241128175519242

class Solution {
    public int maxDepth(TreeNode root) {
        if (root == null) return 0;
        Queue<TreeNode> que = new LinkedList<>();
        que.offer(root);
        int depth = 0;
        while (!que.isEmpty()) {
            int len = que.size();
            // 这个地方一直在处理某一层的所有元素
            while (len > 0) {
                TreeNode node = que.poll();
                if (node.left != null) que.offer(node.left);
                if (node.right != null) que.offer(node.right);
                len--;
            }
            depth++;
        }
        return depth;
    }
}

二叉树的最小深度

image-20241128180435064

我自己编写的代码

我自己编写的代码,和答案的思路差不多

 /**
 * 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 int minDepth(TreeNode root) {
        if (root == null) return 0;
        Queue<TreeNode> que = new LinkedList<>();
        que.offer(root);
        int depth = 0;
        while (!que.isEmpty()) {
            int len = que.size();
            // 这个地方一直在处理某一层的所有元素
            TreeNode node;
            while (len > 0) {
                node = que.poll();
                if (node.left != null) que.offer(node.left);
                if (node.right != null) que.offer(node.right);
                len--;

                // 下面这个地方是我自己加的,只要找到左右子树为空的,说明就到这了
                if (node.left == null && node.right == null) {
                    depth++;
                    return depth;
                }
            }
            depth++;

        }
        return depth;
    }
}

根据答案修改了一下细节

/**
 * 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 int minDepth(TreeNode root) {
        if (root == null) return 0;
        Queue<TreeNode> que = new LinkedList<>();
        que.offer(root);
        int depth = 0;
        while (!que.isEmpty()) {
            int len = que.size();
            // 这个地方一直在处理某一层的所有元素
            depth++;
            while (len > 0) {
                TreeNode node = que.poll();
                
                // 下面这个地方是我自己加的,只要找到左右子树为空的,说明就到这了
                if (node.left == null && node.right == null) {
                    return depth;
                }
                
                if (node.left != null) que.offer(node.left);
                if (node.right != null) que.offer(node.right);
                len--;
            }
        }
        return depth;
    }
}

完全二叉树的节点个数

image-20241129100019815

递归解法

/**
 * 通用递归解法
 */
class Solution {
    public int countNodes(TreeNode root) {
        if (root == null) return 0;
        return countNodes(root.left) + countNodes(root.right) + 1;
    }
}

完全二叉树解法

/**
 * 针对完全二叉树的解法
 * 满二叉树的结点数为:2^depth - 1
 */
class Solution {
    public int countNodes(TreeNode root) {
        if (root == null) return 0;
        TreeNode left = root.left;
        TreeNode right = root.right;
        int leftDepth = 0, rightDepth = 0; // 这里初始为0是有目的的,为了下面求指数方便
        while (left != null) {  // 求左子树深度
            left = left.left;
            leftDepth++;
        }
        while (right != null) { // 求右子树深度
            right = right.right;
            rightDepth++;
        }
        if (leftDepth == rightDepth) {
            return (2 << leftDepth) - 1;    // 注意(2<<1) 相当于2^2,所以leftDepth初始为0
        }
        return countNodes(root.left) + countNodes(root.right) + 1;
    }
}

平衡二叉树

image-20241129114610916

/**
 * 递归法
 */

class Solution {
    public boolean isBalanced(TreeNode root) {
        return getHeight(root) != -1;
    }
    
    private int getHeight(TreeNode root) {
        // 如果发现不是平衡的二叉树,则会直接返回-1
        if (root == null) return 0;
        int leftHeight = getHeight(root.left);
        if (leftHeight == -1) return -1;
        int rightHeight = getHeight(root.right);
        if (rightHeight == -1) return -1;

        // 左右子树高度差大于1,return -1表示已经不是平衡树了
        if (Math.abs(leftHeight - rightHeight) > 1) return -1;
        return Math.max(leftHeight, rightHeight) + 1;
    }
}

二叉树的所有路径

image-20241129125635569

/**
 * 递归法
 */

class Solution {
    public List<String> binaryTreePaths(TreeNode root) {
        List<String> res = new ArrayList<>();   // 存最终的结果
        if (root == null) return res;
        List<Integer> paths = new ArrayList<>();    // 作为结果中的路径
        traversal(root, paths, res);
        return res;
    }
    
    private void traversal(TreeNode root, List<Integer> paths, List<String> res) {
        paths.add(root.val);    // 前序遍历: 根
        // 遇到叶子结点
        if (root.left == null && root.right == null) {
            // 输出
            StringBuilder sb = new StringBuilder(); // StringBuilder用来拼接字符串,速度更快
            for (int i=0; i<paths.size()-1; i++) {
                sb.append(paths.get(i)).append("->");
            }
            sb.append(paths.get(paths.size()-1));   // 记录最后一个节点
            res.add(sb.toString());     // 收集一个路径
            return;
        }
        // 递归和回溯是同时进行,所以要放在同一个花括号里
        if (root.left != null) {
            traversal(root.left, paths, res);
            paths.remove(paths.size()-1);   // 回溯
        }
        if (root.right != null) { // 右
            traversal(root.right, paths, res);
            paths.remove(paths.size() - 1);// 回溯
        }
    }
}

这个代码目前有回溯的内容了,所以理解起来感觉还是有一点困难的。

image-20241129132324819

image-20241129132402264

左叶子之和

image-20241129132641383

/**
 * 递归求解
 */
class Solution {
    public int sumOfLeftLeaves(TreeNode root) {
        if (root == null) return 0;
        int leftValue = sumOfLeftLeaves(root.left);
        int rightValue = sumOfLeftLeaves(root.right);
        
        int midValue = 0;
        // 对于当前根节点,判断其左孩子节点是否是叶子节点
        if (root.left != null && root.left.left == null && root.left.right == null) {
            midValue = root.left.val;
        }
        int sum = midValue + leftValue + rightValue;
        return sum;
    }
}

找树左下角的值

题目的含义是:找最底层当中所有元素的第一个(由左到右)

image-20241202140824336

/**
 * 递归法
 * 使用前序遍历,这样才先优先左边搜索,然后记录深度最大的叶子节点,此时就是树的最后一行最左边的值。
 */
class Solution {
    private int Deep = -1;
    private int value = 0;

    public int findBottomLeftValue(TreeNode root) {
        value = root.val;
        findLeftValue(root, 0);
        return value;
    }

    private void findLeftValue(TreeNode root, int deep) {
        if (root == null) return;
        if (root.left == null && root.right == null) {
            if (deep > Deep) {
                value = root.val;
                Deep = deep;
            }
        }
        if (root.left != null) findLeftValue(root.left, deep+1);
        if (root.right != null) findLeftValue(root.right, deep+1);
    }
}
/**
 * 迭代法
 */
class Solution {
    public int findBottomLeftValue(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        int res = 0;
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i=0;i<size;i++) {
                TreeNode poll = queue.poll();
                if (i == 0) {
                    res = poll.val; // 最先保留左边的值
                }
                if (poll.left != null) {
                    queue.offer(poll.left);
                }
                if (poll.right != null) {
                    queue.offer(poll.right);
                }
            }
        }
        return res;
    }
    
}

路径总和

image-20241202144759671

image-20241202145133228

class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if (root == null) return false;
        targetSum -= root.val;
        // 叶子节点
        if (root.left == null && root.right == null) {
            return targetSum == 0;
        }
        if (root.left != null) {
            boolean left = hasPathSum(root.left, targetSum);
            if (left) return true;  // 已经找到
        }
        if (root.right != null) {
            boolean right = hasPathSum(root.right, targetSum);
            if (right) return true;
        }
        
        return false;
    }
}

二叉树的修改与构造

翻转二叉树

image-20241129092151360

/**
 * 前后序遍历都可以
 * 中序不行,因为先左孩子交换孩子,再根交换孩子(做完后,右孩子已经变成了原来的左孩子),再右孩子交换孩子(此时其实是对原来的左孩子做交换)
 */

class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null) {
            return null;
        }
        swapChildren(root);
        invertTree(root.left);
        invertTree(root.right);
        
        return root;
    }
    
    private void swapChildren(TreeNode root) {
        TreeNode tmp = root.left;
        root.left = root.right;
        root.right = tmp;
    }
}

从中序与后序遍历序列构造二叉树

image-20241202150422610

class Solution {
    Map<Integer, Integer> map;      // 方便根据数值查找位置

    public TreeNode buildTree(int[] inorder, int[] postorder) {
        map = new HashMap<>();
        for (int i=0;i<inorder.length;i++) {
            map.put(inorder[i], i);
        }
        return findNode(inorder, 0, inorder.length, postorder, 0, postorder.length);// 前闭后开
    }

    public TreeNode findNode(int[] inorder, int inBegin, int inEnd, int[] postorder, int postBegin, int postEnd) {
        // 参数里的范围都是前闭后开
        if (inBegin >= inEnd || postBegin >= postEnd) {
            return null;    // 不满足左闭右开,说明没有元素,返回空树
        }
        int rootIndex = map.get(postorder[postEnd - 1]);    // 找到后序遍历的最后一个元素在中序遍历中的位置
        TreeNode root = new TreeNode(inorder[rootIndex]);    // 构造结点
        int lenOfLeft = rootIndex - inBegin;    // 保存中序左子树个数,用来确定后序数列的个数
        root.left = findNode(inorder, inBegin, rootIndex, postorder, postBegin, postBegin+lenOfLeft);
        root.right = findNode(inorder, rootIndex+1, inEnd, postorder, postBegin+lenOfLeft, postEnd-1);

        return root;
    }
}

最大二叉树

image-20241202163921998

image-20241202163944186

image-20241202164003456

class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        return cMBT(nums, 0, nums.length);
    }

    public TreeNode cMBT(int[] nums, int leftIndex, int rightIndex) {   // 左开右闭
        if (rightIndex - leftIndex < 1) return null;    // 没有元素了
        if (rightIndex - leftIndex == 1) return new TreeNode(nums[leftIndex]);  // 只有一个元素
        int maxIndex = leftIndex;   // 最大值所在位置
        int maxVal = nums[maxIndex];    // 最大值
        for (int i=leftIndex+1; i<rightIndex; i++) {   // 找最大值
            if (nums[i] > maxVal) {
                maxVal = nums[i];
                maxIndex = i;
            }
        }
        TreeNode root = new TreeNode(maxVal);
        // 根据maxIndex划分左右子树
        root.left = cMBT(nums, leftIndex, maxIndex);
        root.right = cMBT(nums, maxIndex+1, rightIndex);
        
        return root;
    }
}

合并二叉树

image-20241202170017958

/**
 * 递归法
 */

class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if (root1 == null) return root2;
        if (root2 == null) return root1;
        
        root1.val += root2.val;
        root1.left = mergeTrees(root1.left, root2.left);
        root1.right = mergeTrees(root1.right, root2.right);
        
        return root1;
    }
}

二叉搜索树的属性

二叉搜索树中的搜索

image-20241202170909401

/**
 * 递归,利用二叉搜索树特点,优化
 */
class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if (root == null || root.val == val) return root;
        if (val < root.val) return searchBST(root.left, val);
        else return searchBST(root.right, val);
    }
}

做-验证二叉搜索树

image-20241203182334675

还要继续理清楚逻辑

/**
 * 中序遍历实现。左 < 中 <右
 * pre 记录的是当前节点的前一个节点(中序序列中当前节点的前一个)
 */
class Solution {
    TreeNode pre;
    public boolean isValidBST(TreeNode root) {
        if (root == null) return true;
        // 左子树不满足,则返回
        boolean left = isValidBST(root.left);
        if (!left) return false;
        // 根和前一个比较
        if (pre != null && root.val <= pre.val) {
            return false;
        }
        pre = root;
        // 右子树不满足,则返回
        boolean right = isValidBST(root.right);
        return right;
    }
}

image-20241203193712855

二叉搜索树的最小绝对差

image-20241203193453855

/**
 * 中序遍历实现。左 < 中 <右
 * pre 记录的是当前节点的前一个节点(中序序列中当前节点的前一个)
 */
class Solution {
    TreeNode pre;   // 记录上一个遍历的结点
    int result = Integer.MAX_VALUE;
    public int getMinimumDifference(TreeNode root) {
        if (root == null) return 0;
        traversal(root);
        return result;
    }
    
    public void traversal(TreeNode root) {
        if (root == null) return;   
        // 左
        traversal(root.left);
        // 根
        if (pre != null) {
            result = Math.min(result, root.val - pre.val);
        }
        pre = root;
        // 右
        traversal(root.right);
    }
}

image-20241203193821931

二叉搜索树中的众数

image-20241203195208169

class Solution {
    ArrayList<Integer> resList;
    int maxCount;
    int count;
    TreeNode pre;
    
    public int[] findMode(TreeNode root) {
        resList = new ArrayList<>();
        maxCount = 0;
        count = 0;
        pre = null; // 初始化前一个为null
        findMode1(root);
        int[] res = new int[resList.size()];
        for (int i=0; i<resList.size(); i++) {
            res[i] = resList.get(i);
        }
        return res;
    }
    
    public void findMode1(TreeNode root) {
        if (root == null) return;
        // 左
        findMode1(root.left);
        
        int rootValue = root.val;
        // 计数
        if (pre == null || rootValue != pre.val) {
            count = 1;
        } else {
            count++;
        }
        // 更新结果以及maxCount
        if (count > maxCount) {
            resList.clear();
            resList.add(rootValue);
            maxCount = count;
        } else if (count == maxCount) {
            resList.add(rootValue);
        }
        pre = root;
        
        // 右
        findMode1(root.right);
    }
}

理解清楚里面的逻辑。还是利用二叉搜索树的中序序列递增的特点。

把二叉搜索树转换为累加树

image-20241203201549439

image-20241203201612448

class Solution {
    int sum;
    public TreeNode convertBST(TreeNode root) {
        sum = 0;
        convertBST1(root);
        return root;
    }

    // 按右中左顺序遍历,累加即可
    public void convertBST1(TreeNode root) {
        if (root == null) return;
        // 右
        convertBST1(root.right);
        
        sum += root.val;
        root.val = sum;
        
        // 左
        convertBST1(root.left);
    }
}

image-20241203201743151

二叉树公共祖先问题

做-二叉树的最近公共祖先

image-20241203202350798

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root==null || root==p || root==q) {      // 递归结束条件
            return root;
        }

        // 后序遍历
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        
        if (left==null && right==null) {    // 若未找到节点 p 或 q
            return null;
        } else if (left==null && right!=null) {  // 若找到一个节点
            return right;
        } else if (left!=null && right==null) {     // 若找到一个节点
            return left;
        } else {    // 若找到两个节点
            return root;
        }
    }
}

image-20241210201331159

image-20241210201531091

二叉搜索树的最近公共祖先

image-20241210203645605

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root.val > p.val && root.val > q.val) {
            return lowestCommonAncestor(root.left, p, q);
        }
        if (root.val < p.val && root.val < q.val) {
            return lowestCommonAncestor(root.right, p, q);
        }
        return root;
    }
}

image-20241210205037112

下面这两幅图就是例子:理解上面的递归代码的含义

image-20241210205414184

二叉搜索树的修改与构造

二叉搜索树的插入操作

image-20241210205705065

class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if (root == null) { // 如果当前节点为空,也就意味着val找到了合适的位置,此时创建节点直接返回。
            return new TreeNode(val);
        }
        if (root.val < val) {
            root.right = insertIntoBST(root.right, val);
        } else if (root.val > val) {
            root.left = insertIntoBST(root.left, val);
        }
        return root;
    }
}

删除二叉搜索树中的节点

image-20241210211211967

class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        if (root == null) return root;
        if (root.val == key) {
            if (root.left == null) {
                return root.right;
            } else if (root.right == null) {
                return root.left;
            } else {
                TreeNode cur = root.right;
                while (cur.left != null) {
                    cur = cur.left;
                }
                cur.left = root.left;
                root = root.right;
                return root;
            }
        }
        if (root.val > key) {
            root.left = deleteNode(root.left, key);
        }
        if (root.val < key) {
            root.right = deleteNode(root.right, key);
        }
        return root;
    }
}

image-20241210212544350

修剪二叉搜索树

image-20241210213049193

class Solution {
    public TreeNode trimBST(TreeNode root, int low, int high) {
        if (root == null) return null;
        if (root.val < low) {
            return trimBST(root.right, low, high);
        }
        if (root.val > high) {
            return trimBST(root.left, low, high);
        }

        // root在[low,high]范围内
        root.left = trimBST(root.left, low, high);
        root.right = trimBST(root.right, low, high);
        return root;
    }
}

将有序数组转换为二叉搜索树

image-20241210214011102

class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        return sortedArrayToBST(nums, 0, nums.length);
    }
    
    public TreeNode sortedArrayToBST(int[] nums, int left, int right) {
        if (left >= right) {
            return null;
        }
        if (right - left == 1) {
            return new TreeNode(nums[left]);
        }
        int mid = left + (right - left) / 2;
        TreeNode root = new TreeNode(nums[mid]);
        root.left = sortedArrayToBST(nums, left, mid);
        root.right = sortedArrayToBST(nums, mid + 1, right);
        return root;
    }
}

其实思路也是一样的,不断中间分割,然后递归处理左区间,右区间,也可以说是分治。

image-20241210215655615

总结

节点带有构造函数

image-20241129093700648

递归和迭代

image-20241129093907672

最后,学习内容来源:

1)代码随想录

2)力扣

posted @ 2024-12-11 10:17  墨羽寻觅  阅读(1)  评论(0编辑  收藏  举报