Print numbers from 1 to the largest number with N digits by recursion.

Example
Given N = 1, return [1,2,3,4,5,6,7,8,9].

Given N = 2, return [1,2,3,4,5,6,7,8,9,10,11,12,...,99].

Note
It's pretty easy to do recursion like:

recursion(i) {
    if i > largest number:
        return
    results.add(i)
    recursion(i + 1)
}
however this cost a lot of recursion memory as the recursion depth maybe very large. Can you do it in another way to recursive with at most N depth?

思路

这道题要求我们递归的层数不超过N层,根据这个限制条件我们必须在每一层内把当前这一层的数全部枚举出来。也就是说我们在每一层都需要把N digits的数列举出来。通过观察example可以发现:每一层的数是建立在之前一层的基础上的,也就是我们把上一层的每个数拿出来乘以10,然后分别加上0-9,就可以形成这一层的数。比如上一层的数是10,那么这一层就可以形成100,101,102,103,104,105,106,107,108,109.

用递归的思路来解题,我们需要明确base case和main body。

  • base case: 如果当前count的层数已经大于N,那么我们直接return。

  • main body: 这里头也分为两种情况

  1. 如果count == 1, 那么我们这时候没有上一层的数作为input,所以我们得自己先手动生成结果。然后把output作为input传给下一层。2. 如果count!=1,那么我们就可以直接拿来上一层的input来生成这一层的output,然后再传给下一层。

注意这里如果我们只是这样去做的话,那么最后递归return的时候我们只有最后一层的数,所以我们还需要在调用每次递归前,把生成的结果加入到总的结果当中。

代码

public List<Integer> numbersByRecursion(int n) {
        // write your code here
        List<Integer> finalResult = new ArrayList<Integer>();
        if (n <= 0){
            return finalResult;
        }
        List<Integer> result = new ArrayList<Integer>();
        helper(result, 1, n, finalResult);
        return finalResult;
    }
    public void helper(List<Integer> result, int k, int n, List<Integer> finalResult){
       if (k > n){
           return;
       }
       if (k == 1){
           for (int i = 1; i <= 9; i++){
               result.add(i);
           }
           finalResult.addAll(result);
           helper(result, k + 1, n, finalResult);
       }else{
            List<Integer> temp = new ArrayList<Integer>();
            for (int i = 0; i < result.size(); i++){
                for (int j = 0; j <= 9; j++){
                    temp.add(result.get(i)*10 + j);
                }
            }
            finalResult.addAll(temp);
            helper(temp, k + 1, n, finalResult);
       }
    }

复杂度

时间 O(n*N), 空间 O(N), 这里头n是递归调用的层数, N是所有的数


liut2的算法笔记
0 声望1 粉丝

引用和评论

0 条评论