254. Factor Combinations

254. Factor Combinations


Numbers can be regarded as product of its factors. For example,

8 = 2 x 2 x 2;
= 2 x 4.
Write a function that takes an integer n and return all possible combinations of its factors.

Note:

You may assume that n is always positive.
Factors should be greater than 1 and less than n.
Example 1:

Input: 1
Output: []

Example 2:

Input: 37
Output:[]

Example 3:

Input: 12
Output:
[
  [2, 6],
  [2, 2, 3],
  [3, 4]
]

Example 4:

Input: 32
Output:
[
  [2, 16],
  [2, 2, 8],
  [2, 2, 2, 4],
  [2, 2, 2, 2, 2],
  [2, 4, 4],
  [4, 8]
]

方法1:

思路:

这道题给了我们一个正整数n,让我们写出所有的因子相乘的形式,而且规定了因子从小到大的顺序排列,那么对于这种需要列出所有的情况的题目,通常都是用回溯法来求解的,由于题目中说明了1和n本身不能算其因子,那么我们可以从2开始遍历到n,如果当前的数i可以被n整除,说明i是n的一个因子,我们将其存入一位数组out中,然后递归调用n/i,此时不从2开始遍历,而是从i遍历到n/i,停止的条件是当n等于1时,如果此时out中有因子,我们将这个组合存入结果res中,参见代码如下:

下面这种方法用了个小trick,我们仔细观察题目中给的两个例子的结果,可以发现每个组合的第一个数字都没有超过n的平方根,这个也很好理解,由于要求序列是从小到大排列的,那么如果第一个数字大于了n的平方根,而且n本身又不算因子,那么后面那个因子也必然要与n的平方根,这样乘起来就必然会超过n,所以不会出现这种情况。那么我们刚开始在2到n的平方根之间进行遍历,如果遇到因子,先复制原来的一位数组out为一个新的一位数组new_out,然后把此因子i加入new_out,然后再递归调用n/i,并且从i遍历到n/i的平方根,之后再把n/i放入new_out,并且存入结果res,由于层层迭代的调用,凡是本身能继续拆分成更小因数的都能在之后的迭代中拆分出来,并且加上之前结果,最终都会存res中。

易错点

  1. 终止条件不要再推一次,
  2. 在递归之前要向result中push一次,相当于记录所有中途的路径
class Solution {
public:
    vector<vector<int>> getFactors(int n) {
        vector<vector<int>> result;
        if (n < 2) return result;
        vector<int> current;
        
        factorHelper(result, current, n, 2);
        return result;
    }
        
        void factorHelper(vector<vector<int>> & result, vector<int> & current, int target, int lowerBound){
            if (lowerBound >= target) {
                return;
            }
            
            
            for (int i = lowerBound; i <= sqrt(target); i++){
                if (target % i == 0){
                     current.push_back(i);
                     current.push_back(target / i);
                     result.push_back(current);
                     current.pop_back();
                     factorHelper(result, current, target / i, i);
                     current.pop_back();
                }
            }
            return;
        }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值