[Leetcode] 254. Factor Combinations

既然是要求出所有的解集,并没有特别取巧的方法,就是backtracking自下而上取得结果即可。其实本质上和https://blog.csdn.net/chaochen1407/article/details/80863424这一题是有些类似的。
只需要从最基本的起始数字(第一层是2),不停循环到当前数字,找到模除为0的就往下走一层递归,每一层都有一个base case就是当前层的这个数字(除非这个数字是原来要求的input,因为解集不允许出现1 * n这种解集。) 同时,每往下走一层,起始数字
举个例子, 32
1. 在第一层递归层里面,这里不存在base case,因为这一层的数字就是原来的input。
所以从2开始循环走,然后32能被2整除,所以我们把16作为下一层的结算数字和2作为起始数字传到下一层。
(递归第二层)此时已经有一个base case就是16,直接放进结果数组中,然后再从2走,16被2整除,所以把8作为下一层结算数字和2作为起始数字到下一层。
(递归第三层)此时有一个base case为8,放进结果数组,然后再从2走,8被2整除。下一层
(递归第四层)此时有一个base case为4,同上。再从2走,4被2整除,下一层。
(递归第五层)此时只有一个base case 为2。直接返回[[2]]
(返回递归第四层),第五层返回的2打包进来,返回[[2,2], [4]]
(返回第三层),把第四层返回的结果再打包,返回[[2,2,2],[2,4]] 然后往下计算还可以找到一个4进入递归第四层,但会因为找不到剩余结果而作废
。。。。。。 如此类推

直接给出代码吧,这种递归题都比较难一步步说明,篇幅会略长。

    public List<List<Integer>> getFactors(int n) {
        return _getFactors(n, n, 2);
    }
    
    private List<List<Integer>> _getFactors(int n, int curN, int curNum) {
        List<List<Integer>> result = new LinkedList<>();
        for (int i = curNum; i <= curN; i++) {
            if (curN == i && curN != n) {
                List<Integer> base = new LinkedList<Integer>();
                base.add(i);
                result.add(base);
            } else if (curN % i == 0) {
                List<List<Integer>> subRes = _getFactors(n, curN / i, i);
                for (List<Integer> row : subRes) {
                    LinkedList<Integer> convertedRow = (LinkedList<Integer>) row;
                    convertedRow.addFirst(i);
                    result.add(convertedRow);
                }
            }
        }
        
        return result;
    }

如果直接这样返回,那么,你会得到accept,但时间排名在非常靠后。实际上,在for循环里面,我们不需要到curN,只需要到Math.sqrt(curN)就好了,因为后面即使找到(curN % i == 0)的情况都会被之后的递归层作废。所以优化一下,就可以得到99%时间排名的代码

    public List<List<Integer>> getFactors(int n) {
        return _getFactors(n, n, 2);
    }
    
    private List<List<Integer>> _getFactors(int n, int curN, int curNum) {
        List<List<Integer>> result = new LinkedList<>();
        if (curN != n) {
            List<Integer> base = new LinkedList<Integer>();
            base.add(curN);
            result.add(base);            
        }

        for (int i = curNum; i <= Math.sqrt(curN); i++) {
            if (curN % i == 0) {
                List<List<Integer>> subRes = _getFactors(n, curN / i, i);
                for (List<Integer> row : subRes) {
                    LinkedList<Integer> convertedRow = (LinkedList<Integer>) row;
                    convertedRow.addFirst(i);
                    result.add(convertedRow);
                }
            }
        }
        
        return result;
    }


 

猜你喜欢

转载自blog.csdn.net/chaochen1407/article/details/81278566