Leetcode Recursion递归问题

本文深入探讨了LeetCode上的三个经典算法题目:范围求和的二叉搜索树、第N个Tribonacci数以及所有可能的满二叉树。通过详细的代码示例,解析了这些算法背后的逻辑,包括递归、动态规划和深度优先搜索等核心概念。

938. Range Sum of BST

Given the root node of a binary search tree, return the sum of values of all nodes with value between L and R (inclusive).

The binary search tree is guaranteed to have unique values.

Example 1:

Input: root = [10,5,15,3,7,null,18], L = 7, R = 15
Output: 32

Note:

  1. The number of nodes in the tree is at most 10000.
  2. The final answer is guaranteed to be less than 2^31.
/**
 * 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) {
        int sum = 0;
        if (root == null) {
            return 0;
        }
        
        if (L <= root.val && root.val <= R) {
            sum += root.val;
        }
        
        if (root.left != null) {
            sum += rangeSumBST(root.left, L, R);
        }
        
        if (root.right != null) {
            sum += rangeSumBST(root.right, L, R);
        }
        return sum;
    }
}

1137. N-th Tribonacci Number

The Tribonacci sequence Tn is defined as follows: 

T0 = 0, T1 = 1, T2 = 1, and Tn+3 = Tn + Tn+1 + Tn+2 for n >= 0.

Given n, return the value of Tn.

Example 1:

Input: n = 4
Output: 4
Explanation:
T_3 = 0 + 1 + 1 = 2
T_4 = 1 + 1 + 2 = 4

Constraints:

  • 0 <= n <= 37
  • The answer is guaranteed to fit within a 32-bit integer, ie. answer <= 2^31 - 1.

1. 数组

class Solution {
    public int tribonacci(int n) {
        
        int [] num = new int[n + 3];
        num[0] = 0; num[1] = 1; num[2] = 1;
        
        if (n <= 2)
            return num[n];
        
        for (int i = 3; i <= n; i++) {
            num[i] = num[i - 3] + num[i - 2] + num[i - 1];
        }
        
        return num[n];
   }
}

2.

class Solution {
    
    int [] num = new int[38];
    /*num[0] = 0;         // 出错!为啥
    num[1] = 1; 
    num[2] = 1;*/
    
    public int tribonacci(int n) {
        if (n <= 1)
            return num[n] = n;
        if (n == 2)
            return num[n] = 1;
        
        if (num[n] > 0)
            return num[n];
        else 
            return num[n] = tribonacci(n - 3) + tribonacci(n - 2) + tribonacci(n - 1);

   }
}

3.递推

class Solution {

    public int tribonacci(int n) {
        if (n <= 1)
            return n;
        if (n == 2) 
            return 1;
        
        int a = 0, b = 1, c = 1;
        int sum = a + b + c;
        for (int i = 4; i <= n; i++) {
            a = b;
            b = c;
            c = sum;
            sum = a + b + c;
        }
        return sum;
   }
}

894. All Possible Full Binary Trees

full binary tree is a binary tree where each node has exactly 0 or 2 children.

Return a list of all possible full binary trees with N nodes.  Each element of the answer is the root node of one possible tree.

Each node of each tree in the answer must have node.val = 0.

You may return the final list of trees in any order.

Example 1:

Input: 7
Output: [[0,0,0,null,null,0,0,null,null,0,0],[0,0,0,null,null,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,null,null,null,null,0,0],[0,0,0,0,0,null,null,0,0]]
Explanation:

Note:

  • 1 <= N <= 20

dfs

https://leetcode.com/problems/all-possible-full-binary-trees/discuss/535096/Java-dfs%2Bdp-99

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    Map<Integer, List<TreeNode> > map = new HashMap<>();
    
    public List<TreeNode> allPossibleFBT(int N) {
        List<TreeNode> ans = new ArrayList<>();
        if (N % 2 == 0)
            return ans;
        ans.add(new TreeNode(0));
        map.put(1, ans);
         if (N == 1) {
            return ans;
        }
        return dfs(N);
    }

    public List<TreeNode> dfs(int N) {
        if (N == 1) {
            return map.get(1);
        }
        List<TreeNode> ans = new ArrayList<>();
        
        for (int i = 1; i <= N - 1; i += 2) {
            int left = i;
            int right = N - i - 1;
            if (!map.containsKey(left)) {
                map.put(left, dfs(left));
            }
            if (!map.containsKey(right)) {
                map.put(right, dfs(right));
            }
            
            List<TreeNode> leftNode = map.get(left);
            List<TreeNode> rightNode = map.get(right);
            
            for (int l = 0; l < leftNode.size(); l++) {
                for (int r = 0; r < rightNode.size(); r++) {
                    TreeNode root = new TreeNode(0);
                    root.left = leftNode.get(l);
                    root.right = rightNode.get(r);
                    ans.add(root);
                }
            }
        }
        return ans;
    }
}

698. Partition to K Equal Sum Subsets

Given an array of integers nums and a positive integer k, find whether it's possible to divide this array into k non-empty subsets whose sums are all equal.

Example 1:

Input: nums = [4, 3, 2, 3, 5, 2, 1], k = 4
Output: True
Explanation: It's possible to divide it into 4 subsets (5), (1, 4), (2,3), (2,3) with equal sums.

Note:

  • 1 <= k <= len(nums) <= 16.
  • 0 < nums[i] < 10000.

Reference:

https://leetcode.com/problems/partition-to-k-equal-sum-subsets/discuss/108730/JavaC%2B%2BStraightforward-dfs-solution

Bactrace Introduction:

https://www.geeksforgeeks.org/backtracking-introduction/

class Solution {

    public boolean canPartitionKSubsets(int[] nums, int k) {
        int sum = 0;
        for (int num : nums) {
            sum += num;
        }
        if (k <= 0 || (sum % k != 0)) {
            return false;
        }
        int[] visit = new int[nums.length];
        return backtrace(nums, visit, 0, k, 0, 0, sum / k);
    }

    public boolean backtrace(int[] nums, int[] visit, int start, int k, int cursum, int curnum, int target) {
        
        if (k == 1) return true;
        if (cursum == target && curnum > 0) {
           return backtrace(nums, visit, 0, k - 1, 0, 0, target);
        }
        
        for (int i = start; i < nums.length; i++) {
            if (visit[i] == 0) {
                
               visit[i] = 1;
                if (backtrace(nums, visit, i + 1, k, cursum + nums[i], curnum++, target)) {
                    return true;
                }
                visit[i] = 0;
            }
        }
        return false;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值