LeetCode——二叉树

二叉树

思路【labuladong】

1)是否可以通过遍历一遍二叉树得到答案?如果可以,用一个traverse函数配合外部变量来实现——回溯

2)是否可以定义一个递归函数,通过子问题的答案推导出原问题的答案?如果可以,写出这个递归函数的定义,并充分利用这个函数的返回值——动态规划

*)如果单独抽出一个二叉树节点,它需要做什么事情?需要在什么时候(前/中/后序)做?

1. 二叉树的遍历方式

1)二叉树的前序遍历144简单

// 递归遍历
class Solution {
    // 定义结果列表
    List<Integer> result = new ArrayList<>();
    public List<Integer> preorderTraversal(TreeNode root) {
        // 启动递归
        traverse(root);
        return result;
    }
    public void traverse(TreeNode root) {
        // 递归结束条件
        if (root == null) {
            return;
        }
        // 将root的值加入结果列表
        result.add(root.val);
        // 递归遍历左子树
        traverse(root.left);
        // 递归遍历右子树
        traverse(root.right);
    }
}

// 迭代:使用栈
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        // 保存结果列表
        List<Integer> res = new ArrayList<Integer>();
        // 借助栈实现迭代
        Deque<TreeNode> stk = new LinkedList<TreeNode>();
        while (root != null || !stk.isEmpty()) {
            while (root != null) {
                stk.push(root);
                // 前序
                res.add(root.val);
                root = root.left;
            }
            root = stk.pop();
            root = root.right;
        }
        return res;
    }
}

2)二叉树的中序遍历94简单

 // 递归
// class Solution {
//     public List<Integer> inorderTraversal(TreeNode root) {
//         // 保存结果
//         List<Integer> result = new ArrayList<>();
//         // 开始递归
//         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<>();
        // 栈
        Deque<TreeNode> stack = new LinkedList<>();
        // 迭代
        while (root != null || !stack.isEmpty()) {
            // 左下进栈
            while (root != null) {
                stack.push(root);
                root = root.left;
            }
            // 中序
            root = stack.pop();
            result.add(root.val);
            // 右子树存在入栈,不存在弹出栈中元素继续遍历
            root = root.right;
        }
        return result;
    }
}

3)二叉树的后序遍历145简单

 // 递归
class Solution {
    List<Integer> res = new ArrayList<Integer>();
    public List<Integer> postorderTraversal(TreeNode root) {
        traverse(root);
        return res;
    }
    public void traverse(TreeNode root) {
        if (root == null) {
            return;
        }
        traverse(root.left);
        traverse(root.right);
        res.add(root.val);
    }
}


// 迭代
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        Deque<TreeNode> stk = new LinkedList<TreeNode>();
        // 用prev记录访问历史,看右子树是否已经被访问过,能否将其弹出
        TreeNode prev = null;
        while (root != null || !stk.isEmpty()) {
            while (root != null) {
                stk.push(root);
                root = root.left;
            }
            root = stk.pop();
            // 右子树已经被访问过
            if (root.right == null || prev == root.right) {
                res.add(root.val);
                // 更新历史访问记录,标记该子树已经访问完了
                prev = root;
                // 回溯
                root = null;
            } else {
                // 如果右子树没有被访问,将当前节点压栈,访问右子树
                stk.push(root);
                root = root.right;
            }

        }
        return res;
    }
}

4)二叉树的层序遍历

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        // 思路:定义一个队列,在弹出一个节点的同时将其左右子树加入;每层要放在同一个list中,计算长度确定
        // 定义队列
        Queue<TreeNode> q = new LinkedList<>();
        // 定义结果集
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        if (root == null) {
            return result;    
        }
        q.offer(root);
        while (!q.isEmpty()) {
            List<Integer> level = new ArrayList<>();
            int len = q.size();
            for (int i = 0; i < len; i++) {
                TreeNode node = q.poll();
                level.add(node.val);
                if (node.left != null) {
                    q.offer(node.left);
                }
                if (node.right != null) {
                    q.offer(node.right);
                }
            }
            result.add(level);
        }
        return result;
    }
}

2. 二叉树的属性

1)对称二叉树101简单

 // 广度:每一层都是一个回文
 // 深度:遍历顺序反一下,左子树是左中右,右子树是右中左
class Solution {
    public boolean isSymmetric(TreeNode root) {
        return check(root, root);
    }
    // 递归判断节点值是否相等
    public boolean check(TreeNode leftNode, TreeNode rightNode) {
        if (leftNode == null && rightNode == null) {
            return true;
        }
        if (leftNode == null || rightNode == null) {
            return false;
        }
        return (leftNode.val == rightNode.val) && check(leftNode.left, rightNode.right) && check(leftNode.right, rightNode.left);
    }
}

2)二叉树的最大深度104简单

// 广度优先
// class Solution {
//     public int maxDepth(TreeNode root) {
//         // 思路:层次遍历,每一层的时候,深度加1
//         if (root == null) {
//             return 0;
//         }
//         int deep = 0;
//         Queue<TreeNode> q = new LinkedList<>();
//         q.offer(root);
//         while (!q.isEmpty()) {
//             // deep ++;
//             int len = q.size();
//             System.out.println(len);
//             for (int i = 0; i < len; i++) {
//                 TreeNode node = q.poll();
//                 if (node.left != null) {
//                     q.offer(node.left);
//                 }
//                 if (node.right != null) {
//                     q.offer(node.right);
//                 }
//             }
//             deep ++;
//         }
//         return deep;
//     }
// }

// // 深度优先
// // 分解的思路
// class Solution {
//     public int maxDepth(TreeNode root) {
//         // 思路:递归,空节点退出,一个过程是左右子树的最大值+1
//         if (root == null) {
//             return 0;
//         } else {
//             int leftH = maxDepth(root.left);
//             int rightH = maxDepth(root.right);
//             return Math.max(leftH, rightH) + 1;
//         }
//     }
// }

// 遍历的思路
class Solution {
    // 最大深度
    int maxDepth = 0;
    // 当前深度
    int depth = 0;
    public int maxDepth(TreeNode root) {
        // 思路:递归,空节点退出,一个过程是左右子树的最大值+1
        traverse(root);
        return maxDepth;
    }
    public void traverse(TreeNode root) {
        if (root == null) {
            return;
        }
        depth++;
        maxDepth = Math.max(maxDepth, depth);
        traverse(root.left);
        traverse(root.right);
        depth--;
    }
}

3)二叉树的最小深度111简单

// 递归
 // 分解
// class Solution {
//     // 函数定义:root节点的最小深度
//     public int minDepth(TreeNode root) {
//         // 退出条件
//         if (root == null) {
//             return 0;
//         }
//         if (root.left == null) {
//             return minDepth(root.right) + 1;
//         }
//         if (root.right == null) {
//             return minDepth(root.left) + 1;
//         }
//         return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
//     }
// }


// 递归
class Solution {
    // int depth = 0;
    // int minDepth = Integer.MAX_VALUE;
    public int minDepth(TreeNode root) {
        int result = traverse(root);
        return result;
    }
    public int traverse(TreeNode root) {
        if (root == null) {
            return 0;
        }
        if (root.left == null) {
            return traverse(root.right) + 1;
        }
        if (root.right == null) {
            return traverse(root.left) + 1;
        }
        int l = traverse(root.left);
        int r = traverse(root.right);
        return Math.min(l, r) + 1;
    }
}

4)完全二叉树的节点个数222简单


//  // 遍历
// class Solution {
//     int result;
//     public int countNodes(TreeNode root) {
//         traverse(root);
//         return result;
//     }
//     public void traverse(TreeNode root) {
//         if (root == null) {
//             return;
//         }
//         // int l = traverse(root.left) + 1;
//         // int r = traverse(root.right) + 1;
//         traverse(root.left);
//         traverse(root.right);
//         result ++;
//         // return l + r;
//     }
// }


// 分解
class Solution {
    // 函数定义:根节点的个数
    public int countNodes(TreeNode root) {
        if(root == null) {
            return 0;
        }
        // 左节点的个数
        int l = countNodes(root.left);
        int r = countNodes(root.right);
        return l + r + 1;
    }
}

5)平衡二叉树110简单

//  // 遍历——自顶向下
// class Solution {
//     // 左子树是平衡二叉树,右子树是平衡二叉树,左右子树高度差不超过1
//     public boolean isBalanced(TreeNode root) {
//         if (root == null) {
//             return true;
//         }
//         boolean result = (Math.abs(traverse(root.left) - traverse(root.right)) <= 1);
//         return isBalanced(root.left) && isBalanced(root.right) && result;
//     }
//     // 求深度
//     public int traverse(TreeNode root) {
//         if (root == null) {
//             return 0;
//         }
//         int l = traverse(root.left);
//         int r = traverse(root.right);
//         return Math.max(l, r) + 1;
//     }
// }


// 自底向上——这里用int返回值既解决了二叉树深度的问题,也同时可以判断是否是平衡二叉树
class Solution {
    public boolean isBalanced(TreeNode root) {
        return height(root) >= 0;
    }

    public int height(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int leftHeight = height(root.left);
        int rightHeight = height(root.right);
        // 判断是否平衡
        if (leftHeight == -1 || rightHeight == -1 || Math.abs(leftHeight - rightHeight) > 1) {
            return -1;
        } else {
            return Math.max(leftHeight, rightHeight) + 1;
        }
    }
}

6)二叉树的所有路径257简单

// 遍历,自顶向下,因为路径是从上到下的顺序
class Solution {
    List<String> result = new ArrayList<>();
    // 返回二叉树所有路径
    public List<String> binaryTreePaths(TreeNode root) {
        constructPath(root, "");
        return result;
    }
    // 遍历二叉树
    public void constructPath(TreeNode root, String path) {
        if (root == null) {
            return;
        }
        StringBuffer pathnow = new StringBuffer(path);
        pathnow.append(Integer.toString(root.val));
        if (root.left == null && root.right == null) {
            result.add(pathnow.toString());
        } else {
            pathnow.append("->");
            constructPath(root.left, pathnow.toString());
            constructPath(root.right, pathnow.toString());
        }
    }
}

7)左叶子之和404简单

 // 遍历:遍历到左节点的时候就加
class Solution {
    // 和
    int sum = 0;
    public int sumOfLeftLeaves(TreeNode root) {
        traverse(root, 0);
        return sum;
    }
    public void traverse(TreeNode root, int flag) {
        if (root == null) {
            return;
        }
        if (root.left == null && root.right == null && flag == 1) {
            sum += root.val;
        }
        traverse(root.left, 1);
        traverse(root.right, 0);
    }
}

8)找树左下角的值513中等

 // 遍历
class Solution {
    int curVal = 0;
    int curHeight = 0;
    public int findBottomLeftValue(TreeNode root) {
        traverse(root, 0);
        return curVal;
    }
    public void traverse(TreeNode root, int height) {
        if (root == null) {
            return;
        }
        // 高度加1
        height++;
        traverse(root.left, height);
        traverse(root.right, height);
        // 记录下每层的第一个节点
        if (height > curHeight) {
            curHeight = height;
            curVal = root.val;
        }
    }
}

9)路径总和112简单

// class Solution {
//     public boolean hasPathSum(TreeNode root, int targetSum) {
//         return traverse(root, targetSum, 0);

//     }
//     public boolean traverse (TreeNode root, int targetSum, int sum) {
//         if (root == null) {
//             return false;
//         }
//         sum += root.val;
//         traverse(root.left, targetSum, sum);
//         traverse(root.right, targetSum, sum);
//         if (root.left == null && root.right == null && targetSum == sum) {
//             return true;
//         }
        
//     }
// }

class Solution {
    // 函数定义:root节点到叶子节点的路径和是sum
    public boolean hasPathSum(TreeNode root, int sum) {
        if (root == null) {
            return false;
        }
        if (root.left == null && root.right == null) {
            return sum == root.val;
        }
        return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val);
    }
}

3. 二叉树的修改与改造

1)翻转二叉树226简单

// class Solution {
//     // 翻转以root为根的二叉树,返回root节点
//     public TreeNode invertTree(TreeNode root) {
//         if (root == null) {
//             return root;
//         }
//         // change(root);
//         // 翻转左右节点
//         TreeNode temp = root.left;
//         root.left = root.right;
//         root.right = temp;
//         // 递归左右节点
//         invertTree(root.left);
//         invertTree(root.right);
//         // change(root);
//         return root;
//     }

//     public void change(TreeNode root) {
//         TreeNode temp = root.left;
//         root.left = root.right;
//         root.right = temp;
//     }
// }

class Solution {
    // 翻转以root为根的二叉树,返回root节点
    public TreeNode invertTree(TreeNode root) {
        return traver(root);
    }

    public TreeNode traver(TreeNode root) {
        if (root == null) {
            return root;
        }
        // 交换左右节点
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
        // 继续遍历
        traver(root.left);
        traver(root.right);
        return root;
    }
}

2)构造二叉树——需要画图搞清楚下标

从前序与中序遍历序列构造二叉树105中等

 // 前序的第一个节点是根节点,从中序中找到左右子树的分界点
class Solution {
    // 由中序遍历构建一个HashMap,存放节点值与索引的对应
    HashMap<Integer, Integer> valToIndex = new HashMap<>();
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        // 填充map
        for (int i = 0; i < inorder.length; i++) {
            valToIndex.put(inorder[i], i);
        }
        // 递归构建二叉树
        return build(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
    }

    public TreeNode build(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd) {
        // 结束条件
        if (preStart > preEnd) {
            return null;
        }
        int rootVal = preorder[preStart];
        int index = valToIndex.get(rootVal);
        TreeNode root = new TreeNode(rootVal);
        root.left = build(preorder, preStart + 1, preStart + (index - inStart), inorder, inStart, index - 1);
        root.right = build(preorder, (preStart +index - inStart) + 1, preEnd, inorder, index + 1, inEnd);
        return root;
    }
}

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

class Solution {
    // 定义一个map存放中序遍历中值到索引的映射,方便后续找左右节点分界
    HashMap<Integer, Integer> valToIndex = new HashMap<>();
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        // 遍历中序数组
        for (int i = 0; i < inorder.length; i++) {
            valToIndex.put(inorder[i], i);
        }
        // 递归构建二叉树
        return build(inorder, 0, inorder.length - 1, postorder,  0, postorder.length - 1);
    }
    public TreeNode build (int[] inorder, int inStart, int inEnd, int[] postorder, int postStart, int postEnd) {
        // 结束条件
        if (inStart > inEnd) {
            return null;
        }
        // root 节点的值就是后序遍历数组的最后一个元素
        System.out.println(111);
        int rootVal = postorder[postEnd];

        // 找出rootVal在中序遍历中的索引,就可以分开左右子树
        int index = valToIndex.get(rootVal);

        TreeNode root = new TreeNode(rootVal);
        root.left = build(inorder, inStart, index - 1, postorder, postStart, postStart + (index - inStart) - 1);
        root.right = build(inorder, index + 1, inEnd, postorder, postStart + (index - inStart), postEnd - 1);
        return root;
    }
}

根据前序和后序遍历构造二叉树889中等

class Solution {
    // 定义一个HashMap,存储postorder中值到索引的映射
    HashMap<Integer, Integer> valToIndex = new HashMap<>();
    public TreeNode constructFromPrePost(int[] preorder, int[] postorder) {
        // 填充HashMap
        for (int i = 0; i < postorder.length; i++) {
            valToIndex.put(postorder[i], i);
        }
        // 递归构造二叉树
        return build(preorder, 0, preorder.length - 1, postorder, 0, postorder.length - 1);

    }
    // 递归构造二叉树的算法
    public TreeNode build(int[] preorder, int preStart, int preEnd, int[] postorder, int postStart, int postEnd) {
        // 递归结束条件
        if (preStart > preEnd) {
            return null;
        }
        // 只剩一个根节点
        if (preStart == preEnd) {
            return new TreeNode(preorder[preStart]);
        }
        // 根节点
        int rootVal = preorder[preStart];
        // 左子树的根节点
        int leftRootVal = preorder[preStart + 1];
        // 在后续遍历中寻找左子树根节点的位置,划分左右子树
        int index = valToIndex.get(leftRootVal);
        // 左子树的元素个数
        int leftSize = index - postStart + 1;
        // 构造根节点
        TreeNode root = new TreeNode(rootVal);
        root.left = build(preorder, preStart + 1, preStart + leftSize, postorder, postStart, postStart + leftSize);
        root.right = build(preorder, preStart + leftSize + 1, preEnd, postorder, index + 1, postEnd - 1);
        return root;
    }
}

3)最大二叉树654中等

 // 思路:计算数组的最大值,作为根节点,分别计算出左右的子数组,递归构建树
 // 感想:增加参数个数,可以简化中间计算
class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        // 本次数组的长度
        int len = nums.length;
        if (len == 0) {
            return null;
        }
        // 计算本数组的最大值,以及最大值的位置(方便后续分割成两个子数组)
        int maxVal = -1;
        int maxIndex = -1;
        for (int i = 0; i < len; i++) {
            if (nums[i] > maxVal) {
                maxVal = nums[i];
                maxIndex = i;
            }
        }
        // 给根节点赋值
        TreeNode root = new TreeNode(maxVal);
        // 左子树构建需要的子数组
        int[] leftNums = new int[maxIndex];
        for (int i = 0; i < maxIndex; i++) {
            leftNums[i] = nums[i];
        }
        root.left = constructMaximumBinaryTree(leftNums);
        // 右子树构建需要的子数组
        int[] rightNums = new int[len - maxIndex - 1];
        for (int i = 0; i < len - maxIndex - 1; i++) {
            rightNums[i] = nums[maxIndex + 1 + i];
        }
        root.right = constructMaximumBinaryTree(rightNums);
        return root;
        // return build(nums, 0, nums.length - 1);
    }
    // public TreeNode build(int[] nums, int lo, int hi) {
    //     // int len = nums.length;
    //     // if (len == 0) {
    //     //     return null;
    //     // }
    //     if (lo > hi) {
    //         return null;
    //     }
    //     int maxVal = -1;
    //     int maxIndex = -1;
    //     for (int i = lo; i <= hi; i++) {
    //         if (nums[i] > maxVal) {
    //             maxVal = nums[i];
    //             maxIndex = i;
    //         }
    //     }
    //     TreeNode root = new TreeNode(maxVal);
    //     root.left = build(nums, lo, maxIndex - 1);
    //     root.right = build(nums, maxIndex + 1, hi);
    //     return root;

    //     // int[] leftNums = new int[];
    //     // for (int i = 0; i <= hi - lo + 1; i++) {
    //     //     leftNums[i] = nums[i + lo];
    //     // }
    //     // root.left = constructMaximumBinaryTree(leftNums);
    //     // int[] rightNums = new int[len - maxIndex - 1];
    //     // for (int i = 0; i < len - maxIndex - 1; i++) {
    //     //     rightNums[i] = nums[len - maxIndex + 1 + i];
    //     // }
    //     // root.right = constructMaximumBinaryTree(rightNums);
    // }
}

4)合并二叉树617简单

class Solution {
    // 函数定义:合并两棵树
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if(root1 == null && root2 == null) {
            return root1;
        }
        if (root1 == null && root2 != null) {
            return root2;
        }
        if (root1 != null && root2 == null) {
            return root1;
        }
        root1.val = root1.val + root2.val;
        root1.left = mergeTrees(root1.left, root2.left);
        root1.right = mergeTrees(root1.right, root2.right);
        return root1;
    }
}

5)二叉树展开为链表114中等

 // 思路一:遍历,新构造一个二叉树,不断增加节点——函数返回值为void——>希望在原本二叉树上进行操作
 // 思路二:分解
class Solution {
    // 函数定义:将以root节点为根的二叉树拉平
    public void flatten(TreeNode root) {
        if (root == null) {
            return;
        }
        // 将左子树拉平
        flatten(root.left);
        // 将右子树拉平
        flatten(root.right);

        // 取到拉平后的左右子树
        TreeNode letfNode = root.left;
        TreeNode rightNode = root.right;

        // 将左子树连接到root的右子树
        root.left = null;
        root.right = letfNode;
        // 将原右子树拼接到尾部
        TreeNode p = root;
        while (p.right != null) {
            p = p.right;
        }
        p.right = rightNode;
    }
}

4. 二叉搜索树的属性

1)验证二叉搜索树98中等

 // 思路:左子树根节点 < 根节点 < 右子树根节点  && 左右子树都是二叉搜索树
class Solution {
    // 记录上一个节点的值,初始值为long的最小值
    long pre = Long.MIN_VALUE;
    public boolean isValidBST(TreeNode root) {
        return traverse(root);
    }
    public boolean traverse(TreeNode root) {
        if (root == null) {
            return true;
        }
        // 左子树
        boolean leftT = traverse(root.left);
        if (root.val <= pre) return false;
        pre = root.val;
        // 右子树
        boolean rightT = traverse(root.right);
        // 左子树是二叉搜索树,右子树是二叉搜索树,左子树 < 根 < 右子树
        return leftT && rightT;
    }
}

2)把二叉搜索树转换为累加树538中等

 // 思路:遍历二叉树,利用额外的变量记录二叉树的累计和
class Solution {
    int sum = 0;
    public TreeNode convertBST(TreeNode root) {
        traverse(root);
        return root;
    }
    public void traverse(TreeNode root) {
        if (root == null) {
            return;
        }
        traverse(root.right);
        sum += root.val;
        root. val = sum;
        traverse(root.left);
    }
}

3)二叉搜索树中第K小的元素230中等

class Solution {
    // 记录排名
    int rank = 0;
    // 记录结果
    int result = 0;
    public int kthSmallest(TreeNode root, int k) {
        traverse(root, k);
        return result;
    }
    // 中序遍历
    public void traverse(TreeNode root, int k) {
        if (root == null) {
            return;
        }
        traverse(root.left, k);
        rank++;
        if (rank == k) {
            result = root.val;
            return;
        }
        traverse(root.right, k);
    } 

}

5. 二叉树公共祖先问题

1)二叉树的最近公共祖先236中等

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        // 递归结束条件
        if (root == null || root == p || root == q) {
            return root;
        }
        // 后序遍历
        TreeNode leftT = lowestCommonAncestor(root.left, p, q);
        TreeNode rightT = lowestCommonAncestor(root.right, p, q);
        // 如果没有找到节点p或q
        if (leftT == null && rightT == null) {
            return null;
        } else if (leftT == null && rightT != null) {
            return rightT;
        } else if (leftT != null && rightT == null) {
            return leftT;
        } else {
            return root;
        }
    }
}

2)二叉搜索树的最近公共祖先235中等

// 思路:root应该在pq之间
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        // 如果根节点大于p、q,就往右子树里搜索
        if (p.val > root.val && q.val > root.val) {
            return lowestCommonAncestor(root.right, p, q);
        }
        // 如果根节点小于p、q,就往左子树里搜索
        if (p.val < root.val && q.val < root.val) {
            return lowestCommonAncestor(root.left, p, q);
        }
        return root;
    }
}

6. 二叉搜索树的修改与构造

1)将有序数组转换为二叉搜索树108简单

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

2)删除二叉搜索树中的节点450中等

class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        // 递归结束条件
        if (root == null) {
            return null;
        }
        // 找到了要删除
        if (root.val == key) {
            // 1. 左右子树都为空, 直接删
            if (root.left == null && root.right == null) {
                return null;
            }
            // 2. 左子树为空,右子树接替;右子树为空,左子树接替
            if (root.left == null) {
                return root.right;
            }
            if (root.right == null) {
                return root.left;
            }
            // 3. 左右子树都不为空,使用右子树的最小节点接替
            TreeNode minNode = getMin(root.right);
            root.right = deleteNode(root.right, minNode.val);
            minNode.left = root.left;
            minNode.right = root.right;
            root = minNode;
        } else if (root.val > key) {
            // 要往小了找
            root.left = deleteNode(root.left, key);
        } else if (root.val < key) {
            // 要往大了找
            root.right = deleteNode(root.right, key);
        }
        return root;
    }

    // 找二叉搜索树中最小的节点
    public TreeNode getMin(TreeNode root) {
        while (root.left != null) {
            root = root.left;
        }
        return root;
    }
}

[未完待续……]

  • 16
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值