• 数据结构与算法------二叉树


    二叉树的递归遍历(前-中-后序)

    1. // 前序遍历·递归·LC144_二叉树的前序遍历
    2. class Solution {
    3. public List preorderTraversal(TreeNode root) {
    4. List result = new ArrayList();
    5. preorder(root, result);
    6. return result;
    7. }
    8. public void preorder(TreeNode root, List result) {
    9. if (root == null) {
    10. return;
    11. }
    12. result.add(root.val);
    13. preorder(root.left, result);
    14. preorder(root.right, result);
    15. }
    16. }
    17. // 中序遍历·递归·LC94_二叉树的中序遍历
    18. class Solution {
    19. public List inorderTraversal(TreeNode root) {
    20. List res = new ArrayList<>();
    21. inorder(root, res);
    22. return res;
    23. }
    24. void inorder(TreeNode root, List list) {
    25. if (root == null) {
    26. return;
    27. }
    28. inorder(root.left, list);
    29. list.add(root.val); // 注意这一句
    30. inorder(root.right, list);
    31. }
    32. }
    33. // 后序遍历·递归·LC145_二叉树的后序遍历
    34. class Solution {
    35. public List postorderTraversal(TreeNode root) {
    36. List res = new ArrayList<>();
    37. postorder(root, res);
    38. return res;
    39. }
    40. void postorder(TreeNode root, List list) {
    41. if (root == null) {
    42. return;
    43. }
    44. postorder(root.left, list);
    45. postorder(root.right, list);
    46. list.add(root.val); // 注意这一句
    47. }
    48. }

    二叉树的层次遍历( BFS--迭代方式--借助队列)

    1. //BFS--迭代方式--借助队列
    2. class Solution {
    3. public List> resList = new ArrayList>();
    4. public List> levelOrder(TreeNode root) {
    5. checkFun(root);
    6. return resList;
    7. }
    8. //BFS--迭代方式--借助队列
    9. public void checkFun(TreeNode node) {
    10. if (node == null) return;
    11. Queue que = new LinkedList();
    12. que.offer(node);
    13. while (!que.isEmpty()) {
    14. List itemList = new ArrayList();
    15. int len = que.size();
    16. while (len > 0) {
    17. TreeNode tmpNode = que.poll();
    18. itemList.add(tmpNode.val);
    19. if (tmpNode.left != null) que.offer(tmpNode.left);
    20. if (tmpNode.right != null) que.offer(tmpNode.right);
    21. len--;
    22. }
    23. resList.add(itemList);
    24. }
    25. }
    26. }

    226. 翻转二叉树

    给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

    示例 1:

    输入:root = [4,2,7,1,3,6,9]
    输出:[4,7,2,9,6,3,1]

    示例 2:

    输入:root = [2,1,3]
    输出:[2,3,1]
    

    示例 3:

    输入:root = []
    输出:[]
    
    1. //DFS--递归
    2. class Solution {
    3. public TreeNode invertTree(TreeNode root) {
    4. if(root==null) return root;
    5. TreeNode left=invertTree(root.left);
    6. TreeNode right=invertTree(root.right);
    7. swap(root);
    8. return root;
    9. }
    10. //交换
    11. public void swap(TreeNode root){
    12. TreeNode temp=root.left;
    13. root.left=root.right;
    14. root.right=temp;
    15. }
    16. }
    17. //BFS--层次遍历
    18. class Solution {
    19. public TreeNode invertTree(TreeNode root) {
    20. if(root==null) return null;
    21. Queue queue=new LinkedList<>();
    22. queue.offer(root);
    23. while(!queue.isEmpty()){
    24. int size=queue.size();
    25. while(size-->0){
    26. TreeNode node = queue.poll();
    27. swap(node);
    28. if(node.left!=null) queue.offer(node.left);
    29. if(node.right!=null) queue.offer(node.right);
    30. }
    31. }
    32. return root;
    33. }
    34. public void swap(TreeNode root){
    35. TreeNode temp=root.left;
    36. root.left=root.right;
    37. root.right=temp;
    38. }
    39. }

     101. 对称二叉树

    给你一个二叉树的根节点 root , 检查它是否轴对称。

    示例 1:

    输入:root = [1,2,2,3,4,4,3]
    输出:true

    示例 2:

    输入:root = [1,2,2,null,3,null,3]
    输出:false
    1. //DFS--递归
    2. class Solution {
    3. public boolean isSymmetric(TreeNode root) {
    4. return compare(root.left,root.right);
    5. }
    6. public boolean compare(TreeNode left,TreeNode right){
    7. if(left==null&&right!=null) return false;
    8. if(right==null&&left!=null) return false;
    9. if(left==null&&right==null) return true;
    10. if(left.val!=right.val) return false;
    11. return compare(left.left,right.right)&&compare(left.right,right.left);
    12. }
    13. }
    14. //BFS--层次 队列
    15. class Solution {
    16. public boolean isSymmetric(TreeNode root) {
    17. if(root==null) return true;
    18. Queue queue=new LinkedList<>();
    19. queue.offer(root.left);
    20. queue.offer(root.right);
    21. while(!queue.isEmpty()){
    22. int size=queue.size();
    23. while(size-->0){
    24. TreeNode left=queue.poll();
    25. TreeNode right=queue.poll();
    26. if(left==null&&right!=null) return false;
    27. if(left!=null&&right==null) return false;
    28. if(left==null&&right==null) continue;
    29. if(left.val!=right.val) return false;
    30. queue.offer(left.left);
    31. queue.offer(right.right);
    32. queue.offer(left.right);
    33. queue.offer(right.left);
    34. }
    35. }
    36. return true;
    37. }
    38. }

    111. 二叉树的最小深度

    给定一个二叉树,找出其最小深度。

    最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

    说明:叶子节点是指没有子节点的节点。

    示例 1:

    输入:root = [3,9,20,null,null,15,7]
    输出:2
    

    示例 2:

    输入:root = [2,null,3,null,4,null,5,null,6]
    输出:5
    1. //递归
    2. class Solution {
    3. public int minDepth(TreeNode root) {
    4. if(root==null) return 0;
    5. int res=0;
    6. int leftDepth=minDepth(root.left);
    7. int rightDepth=minDepth(root.right);
    8. if(root.left==null&&root.right!=null){
    9. return rightDepth+1;
    10. }
    11. if(root.left!=null&&root.right==null){
    12. return leftDepth+1;
    13. }
    14. res=Math.min(leftDepth,rightDepth)+1;
    15. return res;
    16. }
    17. }
    18. //BFS 队列
    19. class Solution {
    20. public int minDepth(TreeNode root) {
    21. if(root==null) return 0;
    22. Queue queue=new LinkedList<>();
    23. queue.offer(root);
    24. int depth=0;
    25. while(!queue.isEmpty()){
    26. int size=queue.size();
    27. depth++;
    28. while(size-->0){
    29. TreeNode node=queue.poll();
    30. if(node.left!=null) queue.offer(node.left);
    31. if(node.right!=null) queue.offer(node.right);
    32. if(node.left==null&&node.right==null) return depth;
    33. }
    34. }
    35. return depth;
    36. }
    37. }

    222. 完全二叉树的节点个数

    给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

    完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。

    1. //递归
    2. class Solution {
    3. public int countNodes(TreeNode root) {
    4. if(root==null) return 0;
    5. int res=0;
    6. if(root.left!=null){
    7. res+=countNodes(root.left);
    8. }
    9. if(root.right!=null){
    10. res+=countNodes(root.right);
    11. }
    12. return res+1;
    13. }
    14. }
    15. //BFS
    16. class Solution {
    17. public int countNodes(TreeNode root) {
    18. if(root==null) return 0;
    19. Queue queue=new LinkedList<>();
    20. queue.offer(root);
    21. int res=0;
    22. while(!queue.isEmpty()){
    23. int size=queue.size();
    24. while(size-->0){
    25. TreeNode node=queue.poll();
    26. res++;
    27. if(node.left!=null) queue.offer(node.left);
    28. if(node.right!=null) queue.offer(node.right);
    29. }
    30. }
    31. return res;
    32. }
    33. }

    示例 1:

    输入:root = [1,2,3,4,5,6]
    输出:6
    

    示例 2:

    输入:root = []
    输出:0
    

    示例 3:

    输入:root = [1]
    输出:1

     110. 平衡二叉树

    给定一个二叉树,判断它是否是高度平衡的二叉树。

    本题中,一棵高度平衡二叉树定义为:

    一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。 

    示例 1:

    输入:root = [3,9,20,null,null,15,7]
    输出:true
    

    示例 2:

    输入:root = [1,2,2,3,3,null,null,4,4]
    输出:false

    示例 3:

    输入:root = []
    输出:true
    
    1. //递归
    2. class Solution {
    3. public boolean isBalanced(TreeNode root) {
    4. if(root==null) return true;
    5. int left=hight(root.left);
    6. int right=hight(root.right);
    7. if(Math.abs(right-left)>1){
    8. return false;
    9. }
    10. return isBalanced(root.left)&&isBalanced(root.right);
    11. }
    12. //递归求高度
    13. public int hight(TreeNode root){
    14. if(root==null) return 0;
    15. return Math.max(hight(root.left),hight(root.right))+1;
    16. }
    17. }
    18. //BFS求高度
    19. public int hight(TreeNode root){
    20. if(root==null) return 0;
    21. Queue node = new LinkedList<>();
    22. queue.offer(root);
    23. int res=0;
    24. while(!queue.isEmpty()){
    25. int size=queue.size();
    26. res++;
    27. while(size-->0){
    28. TreeNode node=queue.poll();
    29. if(node.left!=null) queue.offer(node.left);
    30. if(node.right!=null) queue.offer(node.right);
    31. }
    32. }
    33. return res;
    34. }

    257. 二叉树的所有路径

    给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。

    叶子节点 是指没有子节点的节点。

    示例 1:

    输入:root = [1,2,3,null,5]
    输出:["1->2->5","1->3"]
    

    示例 2:

    输入:root = [1]
    输出:["1"]
    1. class Solution {
    2. public List binaryTreePaths(TreeNode root) {
    3. List res=new LinkedList<>();
    4. List path=new LinkedList<>();
    5. getPath(root,res,path);
    6. return res;
    7. }
    8. public void getPath(TreeNode root,List res,List path){
    9. if(root==null) return;
    10. path.add(root.val);
    11. if(root.left==null&&root.right==null){//叶子节点
    12. StringBuilder sb=new StringBuilder();
    13. for(int i=0;i1;i++){
    14. sb.append(path.get(i)).append("->");
    15. }
    16. sb.append(path.get(path.size()-1));//处理最后一个节点
    17. res.add(sb.toString());
    18. }
    19. if(root.left!=null){
    20. getPath(root.left,res,path);
    21. path.remove(path.size()-1);
    22. }
    23. if(root.right!=null){
    24. getPath(root.right,res,path);
    25. path.remove(path.size()-1);
    26. }
    27. }
    28. }

    404. 左叶子之和

    给定二叉树的根节点 root ,返回所有左叶子之和。

    示例 1:

    转存失败重新上传取消

    输入: root = [3,9,20,null,null,15,7] 
    输出: 24 
    解释: 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24

    示例 2:

    输入: root = [1]
    输出: 0
    1. //DFS 递归
    2. class Solution {
    3. public int sumOfLeftLeaves(TreeNode root) {
    4. if(root==null) return 0;
    5. int left=sumOfLeftLeaves(root.left);
    6. int right=sumOfLeftLeaves(root.right);
    7. int value=0;
    8. if(root.left!=null&&root.left.left==null&&root.left.right==null){
    9. value+=root.left.val;
    10. }
    11. int res=left+right+value;
    12. return res;
    13. }
    14. }
    15. //BFS 层次 队列
    16. class Solution {
    17. public int sumOfLeftLeaves(TreeNode root) {
    18. if(root==null || root.left==null&&root.right==null) return 0;
    19. Queue queue=new LinkedList<>();
    20. queue.offer(root);
    21. int sum=0;
    22. while(!queue.isEmpty()){
    23. int size=queue.size();
    24. while(size-->0){
    25. TreeNode node=queue.poll();
    26. if(node.left!=null) {
    27. if(node.left.left==null&&node.left.right==null){
    28. sum+=node.left.val;
    29. }
    30. queue.offer(node.left);
    31. }
    32. if(node.right!=null){
    33. queue.offer(node.right);
    34. }
    35. }
    36. }
    37. return sum;
    38. }
    39. }

    这题在层次遍历中出错,直接在node.left!=null里面判断是左叶子就行 

    这题关键点是:1.找左叶子 2.左叶子的判断是root.left!=null&&root.left.left==null&&root.left.right==null

    513. 找树左下角的值

    给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。

    假设二叉树中至少有一个节点。

    示例 1:

    输入: root = [2,1,3]
    输出: 1

    示例 2:

    输入: [1,2,3,4,null,5,6,null,null,7]
    输出: 7
    1. // 递归法
    2. class Solution {
    3. private int Deep = -1;
    4. private int value = 0;
    5. public int findBottomLeftValue(TreeNode root) {
    6. value = root.val;
    7. findLeftValue(root,0);
    8. return value;
    9. }
    10. private void findLeftValue (TreeNode root,int deep) {
    11. if (root == null) return;
    12. if (root.left == null && root.right == null) {//到叶子节点
    13. if (deep > Deep) {
    14. value = root.val;
    15. Deep = deep;//到最大深度
    16. }
    17. }
    18. findLeftValue(root.left,deep + 1);
    19. findLeftValue(root.right,deep + 1);
    20. }
    21. }
    22. //BFS 层次
    23. class Solution {
    24. public int findBottomLeftValue(TreeNode root) {
    25. if(root==null) return 0;
    26. if(root.left==null&&root.right==null) return root.val;
    27. Queue queue=new LinkedList<>();
    28. queue.offer(root);
    29. int res=0;
    30. while(!queue.isEmpty()){
    31. int size=queue.size();
    32. while(size-->0){
    33. TreeNode node=queue.poll();
    34. if(size==0) res=node.val;
    35. if(node.right!=null) {
    36. queue.offer(node.right);
    37. }
    38. if(node.left!=null) {
    39. queue.offer(node.left);
    40. }
    41. }
    42. }
    43. return res;
    44. }
    45. }

    本题递归需要注意的是:1 先找叶子节点 2 找最大深度  层次遍历只需要每次更新size=0即最左边的节点的值

    112. 路径总和

    给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。

    叶子节点 是指没有子节点的节点。

    示例 1:

    输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
    输出:true
    解释:等于目标和的根节点到叶节点路径如上图所示。

    示例 2:

    输入:root = [1,2,3], targetSum = 5
    输出:false
    解释:树中存在两条根节点到叶子节点的路径:
    (1 --> 2): 和为 3
    (1 --> 3): 和为 4
    不存在 sum = 5 的根节点到叶子节点的路径。
    示例 3:

    输入:root = [], targetSum = 0
    输出:false
    解释:由于树是空的,所以不存在根节点到叶子节点的路径。

    1. class Solution {
    2. public boolean hasPathSum(TreeNode root, int targetSum) {
    3. if(root==null) return false;
    4. targetSum-=root.val;
    5. if(root.left==null&&root.right==null&&targetSum==0) return true;
    6. if(root.left!=null) {
    7. if(hasPathSum(root.left,targetSum))
    8. return true;
    9. }
    10. if(root.right!=null){
    11. if(hasPathSum(root.right,targetSum))
    12. return true;
    13. }
    14. return false;
    15. }
    16. }
    1. class Solution {
    2. public TreeNode buildTree(int[] inorder, int[] postorder) {
    3. if(inorder.length==0 || postorder.length==0) return null;
    4. return build(inorder,0,inorder.length,postorder,0,postorder.length);
    5. }
    6. public TreeNode build(int[] inorder,int inorderLeft,int inorderRight,int[] postorder,int posLeft,int posRight){
    7. int rootValue=postorder[postRight-1];//找到后序节点的尾节点 该节点为原树的头节点
    8. TreeNode root=new TreeNode(rootValue);//构造头节点
    9. int rootIndex=0;
    10. for(int i=inorderLeft;i//在中序中找到分割点
    11. if(rootValue==inorder[i]){
    12. rootIndex=i;
    13. break;
    14. }
    15. }
    16. //递归
    17. root.left=build(inorder,inorderLeft,rootInex,postorder,posLeft,posLeft+(rootIndex-inorderLeft));
    18. root.right=build(inorder,rootIndex+1,inorderRight,postorder,posLeft+(rootIndex-1),posRight);
    19. }
    20. }

    654. 最大二叉树

    给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:

    创建一个根节点,其值为 nums 中的最大值。
    递归地在最大值 左边 的 子数组前缀上 构建左子树。
    递归地在最大值 右边 的 子数组后缀上 构建右子树。
    返回 nums 构建的 最大二叉树 。

    示例 1:

    输入:nums = [3,2,1,6,0,5]
    输出:[6,3,5,null,2,0,null,null,1]
    解释:递归调用如下所示:
    - [3,2,1,6,0,5] 中的最大值是 6 ,左边部分是 [3,2,1] ,右边部分是 [0,5] 。
        - [3,2,1] 中的最大值是 3 ,左边部分是 [] ,右边部分是 [2,1] 。
            - 空数组,无子节点。
            - [2,1] 中的最大值是 2 ,左边部分是 [] ,右边部分是 [1] 。
                - 空数组,无子节点。
                - 只有一个元素,所以子节点是一个值为 1 的节点。
        - [0,5] 中的最大值是 5 ,左边部分是 [0] ,右边部分是 [] 。
            - 只有一个元素,所以子节点是一个值为 0 的节点。
            - 空数组,无子节点。

    示例 2:

    输入:nums = [3,2,1]
    输出:[3,null,2,null,1]
    
    1. class Solution {
    2. public TreeNode constructMaximumBinaryTree(int[] nums) {
    3. if(nums.length==0) return null;
    4. return build(nums,0,nums.length);
    5. }
    6. public TreeNode build(int[] nums,int left,int right){
    7. if(right-left<1) return null;
    8. if(right-left==1) return new TreeNode(nums[left]);
    9. int rootValue=0;
    10. int rootIndex=0;
    11. for(int i=0;i
    12. if(nums[i]>rootValue){
    13. rootValue=nums[i];
    14. rootIndex=i;
    15. }
    16. }
    17. TreeNode root=new TreeNode(rootValue);
    18. root.left=build(nums,left,rootIndex);
    19. root.right=build(nums,rootIndex+1,right);
    20. return root;
    21. }
    22. }

    617. 合并二叉树

    给你两棵二叉树: root1 和 root2 。

    想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。

    返回合并后的二叉树。

    示例 1:

    输入:root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
    输出:[3,4,5,5,4,null,7]
    示例 2:

    输入:root1 = [1], root2 = [1,2]
    输出:[2,2]

    1. class Solution {
    2. public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
    3. if(root1==null&&root2==null) return null;
    4. if(root1==null&&root2!=null) return root2;//root2不为空 返回root2
    5. if(root1!=null&&root2==null) return root1;//root1不为空 返回root2
    6. TreeNode root=new TreeNode(root1.val+root2.val);//创建新的节点
    7. root.left=mergeTrees(root1.left,root2.left);//合并左节点
    8. root.right=mergeTrees(root1.right,root2.right);//合并右节点
    9. return root;
    10. }
    11. }

    700. 二叉搜索树中的搜索

    给定二叉搜索树(BST)的根节点 root 和一个整数值 val。

    你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。

    示例 1:

    输入:root = [4,2,7,1,3], val = 2
    输出:[2,1,3]
    

    示例 2:

    输入:root = [4,2,7,1,3], val = 5
    输出:[]
    
    1. //利用二叉搜索树的性质
    2. class Solution {
    3. public TreeNode searchBST(TreeNode root, int val) {
    4. if(root==null) return null;
    5. if(root.val==val) return root;
    6. if(val
    7. return searchBST(root.left,val);
    8. }else if(val>root.val){
    9. return searchBST(root.right,val);
    10. }
    11. return root;
    12. }
    13. }

    98. 验证二叉搜索树

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

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

    节点的左子树只包含 小于 当前节点的数。
    节点的右子树只包含 大于 当前节点的数。
    所有左子树和右子树自身必须也是二叉搜索树。

    示例 1:

    输入:root = [2,1,3]
    输出:true
    
    1. class Solution {
    2. public boolean isValidBST(TreeNode root) {
    3. return isBST(root,null,null);
    4. }
    5. public boolean isBST(TreeNode root,TreeNode min,TreeNode max){
    6. if(root==null) return true;
    7. if(min!=null&&root.val<=min.val) return false;
    8. if(max!=null&&root.val>=max.val) return false;
    9. return isBST(root.left,min,root)&&isBST(root.right,root,max);
    10. }
    11. }

    530. 二叉搜索树的最小绝对差

    给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。

    差值是一个正数,其数值等于两值之差的绝对值。

    示例 1:

    输入:root = [4,2,6,1,3]
    输出:

    示例 2:

    输入:root = [1,0,48,null,null,12,49]
    输出:1

    注意:如果出现二叉搜索树求最值,差值之类的,把它转化成有序数组,然后中序遍历

    1. class Solution {
    2. TreeNode pre;
    3. int res=Integer.MAX_VALUE;
    4. public int getMinimumDifference(TreeNode root) {
    5. if(root==null) return 0;
    6. traval(root);
    7. return res;
    8. }
    9. public void traval(TreeNode root){
    10. if(root==null) return;
    11. traval(root.left);
    12. if(pre!=null){
    13. res=Math.min(res,root.val-pre.val);
    14. }
    15. pre=root;
    16. traval(root.right);
    17. }
    18. }

    236. 二叉树的最近公共祖先

    给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

    百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

    示例 1:

    输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
    输出:3
    解释:节点 5 和节点 1 的最近公共祖先是节点 3 。

    示例 2:

    输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
    输出:5
    解释:节点 5 和节点 4 的最近公共祖先是节点 5 。因为根据定义最近公共祖先节点可以为节点本身。

    1. class Solution {
    2. public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    3. if(root==null || root==p || root==q) return root;
    4. TreeNode left=lowestCommonAncestor(root.left,p,q);
    5. TreeNode right=lowestCommonAncestor(root.right,p,q);
    6. if(left==null&&right==null) return null;
    7. if(left==null && right!=null) return right;
    8. if(left!=null && right==null) return left;
    9. return root;
    10. }
    11. }

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

    给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

    百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

    示例 1:

    输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
    输出: 6 
    解释: 节点 2 和节点 8 的最近公共祖先是 6。

    示例 2:

    输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
    输出: 2
    解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。

    1. class Solution {
    2. public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    3. if(root==null || root==p || root==q) return root;
    4. TreeNode left=lowestCommonAncestor(root.left,p,q);
    5. TreeNode right=lowestCommonAncestor(root.right,p,q);
    6. if(root.valreturn left;
    7. if(root.val>p.val&&root.val>q.val) return right;
    8. return root;
    9. }
    10. }

    701. 二叉搜索树中的插入操作

    给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。

    注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回 任意有效的结果 。

    示例 1:

    输入:root = [4,2,7,1,3], val = 5
    输出:[4,2,7,1,3,5]
    解释:另一个满足题目要求可以通过的树是:

    示例 2:

    输入:root = [40,20,60,10,30,50,70], val = 25
    输出:[40,20,60,10,30,50,70,null,null,25]

    示例 3:

    输入:root = [4,2,7,1,3,null,null,null,null,null,null], val = 5
    输出:[4,2,7,1,3,5]

    1. class Solution {
    2. public TreeNode insertIntoBST(TreeNode root, int val) {
    3. if(root==null) return new TreeNode(val);
    4. if(root.val>val) root.left=insertIntoBST(root.left,val);
    5. if(root.val
    6. return root;
    7. }
    8. }

    450. 删除二叉搜索树中的节点

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

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

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

    示例 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
    输出: []

    1. class Solution {
    2. public TreeNode deleteNode(TreeNode root, int key) {
    3. if(root==null) return null;
    4. if(root.val==key){
    5. if(root.left==null){
    6. return root.right;
    7. }else if(root.right==null){
    8. return root.left;
    9. }else{
    10. TreeNode cur=root.right;
    11. while(cur.left!=null){
    12. cur=cur.left;
    13. }
    14. cur.left=root.left;
    15. root=root.right;
    16. return root;
    17. }
    18. }
    19. if(root.val>key) root.left=deleteNode(root.left,key);
    20. if(root.val
    21. return root;
    22. }
    23. }

    669. 修剪二叉搜索树 

    给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。

    所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。

    示例 1:

    输入:root = [1,0,2], low = 1, high = 2
    输出:[1,null,2]

    示例 2:

    输入:root = [3,0,4,null,2,null,null,1], low = 1, high = 3
    输出:[3,2,null,1]
    1. class Solution {
    2. public TreeNode trimBST(TreeNode root, int low, int high) {
    3. if(root==null) return null;
    4. if(root.val>low){
    5. TreeNode left=trimBST(root.left,low,high);//寻找符合区间
    6. return left;
    7. }
    8. if(root.val
    9. TreeNode right=trimBST(root.right,low,high);//寻找符合区间
    10. return right;
    11. }
    12. root.left=trimBST(root.left,low,high);
    13. root.right=trimBST(root.right,low,high);
    14. return root;
    15. }
    16. }

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

    给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。

    高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。

    示例 1:

    输入:nums = [-10,-3,0,5,9]
    输出:[0,-3,9,-10,null,5]
    解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:

    示例 2:

     

     

    输入:nums = [1,3]
    输出:[3,1]
    解释:[1,null,3] 和 [3,1] 都是高度平衡二叉搜索树。
    
    1. class Solution {
    2. public TreeNode sortedArrayToBST(int[] nums) {
    3. if(nums.length==0) return null;
    4. return travel(nums,0,nums.length-1);
    5. }
    6. public TreeNode travel(int[] nums,int left,int right){
    7. if(left>right) return null;
    8. int mid=left+(right-left)/2;
    9. TreeNode root=new TreeNode(nums[mid]);//构造头节点
    10. root.left=travel(nums,left,mid-1);//构造左节点
    11. root.right=travel(nums,mid+1,right);//构造右节点
    12. return root;
    13. }
    14. }

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

    给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。

     

    示例 1:

    输入:[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]
    输出:[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]

    示例 2:

    输入:root = [0,null,1]
    输出:[1,null,1]
    示例 3:

    输入:root = [1,0,2]
    输出:[3,3,2]
    示例 4:

    输入:root = [3,2,4,1]
    输出:[7,9,4,10]

    思路:采用中序遍历的逆序,也就是右中左的顺序

    1. class Solution {
    2. int pre=0;
    3. public TreeNode convertBST(TreeNode root) {
    4. return travel(root);
    5. }
    6. public TreeNode travel(TreeNode root){
    7. if(root==null) null;
    8. travel(root.right);//右
    9. root.val+=pre;//中
    10. pre=root.val;
    11. travel(root.left);//左
    12. return root;
    13. }
    14. }

     

     

     

  • 相关阅读:
    在Win11的子系统中安装 Ubuntu ,并安装DotNet
    mongodb
    JUC 笔记 8
    C++入门及简单例子_4
    【 Git 】 Merge or Rebase
    正则表达式转换为相应的文字小工具
    评价——层次分析
    基于ssm+mysql+jsp作业管理(在线学习)系统
    学习响应式布局
    Linux企业运维之git的使用
  • 原文地址:https://blog.csdn.net/weixin_46345400/article/details/125986153