zoukankan      html  css  js  c++  java
  • 二叉树递归解题

    83.删除排序中的重复元素

    难度 简单

    给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。

    示例1:

      输入: 1->1->2
      输出: 1->2
    

    示例2:

      输入: 1->1->2->3->3
      输出: 1->2->3
    

    Solution

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode deleteDuplicates(ListNode head) {
            if (head == null || head.next == null)
                return head;
            head.next = deleteDuplicates(head.next);
            if (head.val == head.next.val)
                head = head.next;
            return head;
        }
    }
    

    101.对称二叉树

    难度 简单

    给定一个二叉树,检查它是否是镜像对称的。

    示例1:

      二叉树 [1,2,2,3,4,4,3] 是对称的。
    
          1
         / 
        2   2
       /  / 
      3  4 4  3
    

    示例2:

      [1,2,2,null,3,null,3] 则不是镜像对称的:
    
          1
         / 
        2   2
            
         3    3
    

    解题思路

      递归问题解决步骤:
      1. 找整个递归的终止条件:递归应该在什么时候结束?
      2. 找到返回值:应该给上一级返回什么信息?
      3. 本级递归应该做什么:在这一级递归中,应该完成什么任务?
      [参考博客](https://lyl0724.github.io/2020/01/25/1/)
    

    在这个题目中,目的是检查给定的二叉树是否镜像对称,套用递归解题步骤:


    1. 找终止条件。树为空的时候递归结束。


    2. 找返回值。此题是判断给定的二叉树是否镜像对称,因此返回true或者false。


    3. 本级递归应该做什么。给定的函数isSymmetric()的传参只有一个root,而判断二叉树是否镜像,根节点root的左节点left和右节点right的值要相等,而且左节点left的左节点要等于右节点right的右节点,同时左节点left的右节点要等于右节点的左节点(此处的相等为val相等)。另写一个函数,传入左节点left和右节点right,判断是否镜像。

    Solution

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        public boolean isSymmetric(TreeNode root) {
            if (root == null)
                return true;
            return helper(root.left, root.right);
        }
    
        public boolean helper(TreeNode left, TreeNode right){
            if (left == null && right == null)
                return true;
            if (left == null || right == null)
                return false;
            if (left.val == right.val)
                return helper(left.left, right.right)
                    && helper(left.right, right.left);
            return false;
        }
    }
    

    110.平衡二叉树

    难度 简单

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

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

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

    示例1:

      给定二叉树 [3,9,20,null,null,15,7]
    
          3
         / 
        9  20
          /  
         15   7
      返回 true 
    

    示例2:

      给定二叉树 [1,2,2,3,3,null,null,4,4]
    
             1
            / 
           2   2
          / 
         3   3
        / 
       4   4
      返回 false 
    

    解题思路

    helper返回-1或者是平衡树的高度,即如果是平衡树,则返回值》=0。
    helper函数中进行递归:
     1. 边界条件:root == null
     2. 计算左子树的高度
     3. 计算右子树的高度
     4. 判断是否为平衡树
       是:
         返回高度值
       不是:
         返回-1

    Solution

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        public boolean isBalanced(TreeNode root) {
            return helper(root) >= 0;
        }
        public int helper(TreeNode root){
            if (root == null)
                return 0;
            int leftDepth = helper(root.left);
            int rightDepth = helper(root.right);
            if (leftDepth >=0 && rightDepth >= 0 && Math.abs(leftDepth - rightDepth) <= 1)
                return Math.max(leftDepth, rightDepth) + 1;
            else 
                return -1; 
        }
    }
    

    226.翻转二叉树

    难度 简单

    翻转一棵二叉树。

    示例:

      输入:
           4
         /   
        2     7
       /    / 
      1   3 6   9
    
      输出:
           4
         /   
        7     2
       /    / 
      9   6 3   1
    

    解题思路:

    乍一看,感觉和镜像二叉树十分相似,只是将判断节点值是否相等变成交换值。但是进一步思考后,其实不用这么复杂,每个节点依次递归,在本级递归中只需要将左右节点互换就OK。

    Solution

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        public TreeNode invertTree(TreeNode root) {
            if (root == null)
                return null;
            if (root.left == null && root.right == null)
                return root;
            if (root.left != null && root.right == null){
                root.right = root.left;
                root.left = null;
            }else if(root.left == null && root.right != null){
                root.left = root.right;
                root.right = null;
            }else{
                TreeNode temp = root.left;
                root.left = root.right;
                root.right = temp;
            }
            root.left = invertTree(root.left);
            root.right = invertTree(root.right);
            return root;   
        }
    }
    

    654.最大二叉树

    难度 中等

    给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:

    二叉树的根是数组中的最大元素。
    左子树是通过数组中最大值左边部分构造出的最大二叉树。
    右子树是通过数组中最大值右边部分构造出的最大二叉树。
    通过给定的数组构建最大二叉树,并且输出这个树的根节点。

    示例:

      输入:[3,2,1,6,0,5]
      输出:返回下面这棵树的根节点:
      
            6
          /   
         3     5
              / 
           2  0   
             
              1
    

    解题思路:

    第一次提交的代码超出了内存限制,可能是因为递归传参是数组,每次复制原数组的切片。参考大佬的代码后,其实只需要数组nums,左起始位left和终点位right,递归边界是left > right,观察代码其本质为前序遍历:先完成本级的任务,左节点进行递归,右节点再进行递归,结束返回结果,完成。

    Solution

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        public TreeNode constructMaximumBinaryTree(int[] nums) {
            return maxTree(nums, 0, nums.length - 1);
        }
            
        public TreeNode maxTree(int[] nums, int l, int r){
            if (l > r)
                return null;
            int max = findMax(nums, l, r);
            TreeNode root = new TreeNode(nums[max]);
            root.left = maxTree(nums, l, max-1);
            root.right = maxTree(nums, max+1, r);
            return root;
        }
    
        public int findMax(int[] nums, int l, int r){
            int max = Integer.MIN_VALUE, maxIndex = l;
            for (int i = l; i <= r; i++){
                if (max < nums[i]){
                    max = nums[i];
                    maxIndex = i;
                }
            }
            return maxIndex;
        }
    }
    

    938.二叉搜索树的范围和

    难度 简单

    给定二叉搜索树的根结点 root,返回 L 和 R(含)之间的所有结点的值的和。

    二叉搜索树保证具有唯一的值。

    示例1:

      输入:root = [10,5,15,3,7,null,18], L = 7, R = 15
      输出:32
    

    示例2:

      输入:root = [10,5,15,3,7,13,18,1,null,6], L = 6, R = 10
      输出:23
    

    解题思路:

    二叉搜索树的特点:左子树所有的值都比节点的值小,而右子树所有的值都比其大。

    1. 递归边界:root == null
    2. 本级任务:先判断节点的值处于哪个范围
        1)小于L:去右子树找
        2)处于寻找范围:进行加法
        3)大于R:去左子树找
    3. 返回值:节点值 + 左边的值 + 右边的值

    Solution

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        public int rangeSumBST(TreeNode root, int L, int R) {
            if (root == null)
                return 0;
            if (root.val >= L && root.val <= R)
                return root.val + rangeSumBST(root.left, L, R) + rangeSumBST(root.right, L, R);
            else if (root.val < L)
                return rangeSumBST(root.right, L, R);
            else
                return rangeSumBST(root.left, L, R);
            
        }
    }
    

    剑指Offer 54.二叉搜索树的第k大节点

    难度 简单

    给定一棵二叉搜索树,请找出其中第k大的节点。

    示例1:

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

    示例2:

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

    解题思路:

    需要全局变量记录ans和count,本质时中序遍历

    1. 递归边界:++count == k
    2. 本级任务:判断count是否等于k,满足条件直接返回退出。

    Solution

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        private int ans = 0, count = 0;
    
        public int kthLargest(TreeNode root, int k) {
            
            helper(root, k);
            return ans;
        }
        public void helper(TreeNode root, int k){
            if (root.right != null)
                helper(root.right, k);
            if (++count == k){
                ans = root.val;
                return;
            }
            if (root.left != null)
                helper(root.left, k);
        }
    }
    
  • 相关阅读:
    s3fs 挂载minio为本地文件系统
    P5787 线段树分治
    P5494 线段树分裂
    P1552 [APIO2012]派遣
    CF600E Lomsat gelral(线段树合并)
    P5283 异或粽子
    P4735 最大异或和(可持久化 trie)
    P3960 列队
    bzoj4316 小C的独立集
    P5021 赛道修建
  • 原文地址:https://www.cnblogs.com/ly-leah/p/13528104.html
Copyright © 2011-2022 走看看