254 Factor Combinations

Numbers can be regarded as product of its factors. For example,
= 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: 
Each combination's factors must be sorted ascending, for example: The factors of 2 and 6 is [2, 6], not [6, 2].
You may assume that n is always positive.
Factors should be greater than 1 and less than n.
Examples: 
input: 1
output: 
[]
input: 37
output: 
[]
input: 12
output:
[
  [2, 6],
  [2, 2, 3],
  [3, 4]
]
input: 32
output:
[
  [2, 16],
  [2, 2, 8],
  [2, 2, 2, 4],
  [2, 2, 2, 2, 2],
  [2, 4, 4],
  [4, 8]
]

这题就是不停的DFS, 直到 n == 1. 有个判断条件 if (item.size() > 1)  是为了防止答案是自己本身n, 按照题意, 这是不允许的.

参考了:http://www.meetqun.com/thread-10673-1-1.html

时间复杂度, 个人觉得是O(n*log(n)), 一开始觉得是O(n!), 但後来想想好像没那麽大. 我的想法是,
最一开始的for回圈是n, 但是一旦进入了下一个DFS, 每次最差都是 n / i在减小, 这边就是log(n), 所以总共是O(n*log(n)), 有错还请指正.

Update: 使用@yuhangjiang的方法,只用计算 2到sqrt(n)的这么多因子,大大提高了速度。

复制代码
public class Solution {
    public List<List<Integer>> getFactors(int n) {
        List<List<Integer>> res =  new ArrayList<>();
        if (n <= 1) return res;
        getFactors(res, new ArrayList<>(), n, 2);
        return res;
    }
    
    private void getFactors(List<List<Integer>> res, List<Integer> list, int n, int pos) {
        for (int i = pos; i <= Math.sqrt(n); i++) {
            if (n % i == 0 && n / i >= i) {
                list.add(i);
                list.add(n / i);
                res.add(new ArrayList<>(list));
                list.remove(list.size() - 1);
                getFactors(res, list, n / i, i);
                list.remove(list.size() - 1);
            }
        }
    }
}

  

 

 

public class Solution {
    public List<List<Integer>> getFactors(int n) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        List<Integer> item = new ArrayList<Integer>();
        if (n <= 3) return res;
        helper(2, n, res, item);
        return res;
    }
    
    public void helper(int start, int n, List<List<Integer>> res, List<Integer> item) {
        if (n == 1) {
            if (item.size() > 1) {
                res.add(new ArrayList<Integer>(item));
                return;
            }
        }
        for (int i=start; i<=n; i++) {
            if (n%i == 0) {
                item.add(i);
                helper(i, n/i, res, item);
                item.remove(item.size()-1);
            }
        }
    }
}

 

The n is divided by i in each iteration. So we have:

(first iteration)

getFactorsHelper(n/2,2,current,result) = T(n/2)

(second iteration)

getFactorsHelper(n/3,3,current,result) <= getFactorsHelper(n/3,2,current,result) = T(n/3)

(third iteration)

getFactorsHelper(n/4,4,current,result) <= getFactorsHelper(n/4,2,current,result) 
= T(n/4)

...

(final iteration)

getFactorsHelper(n/n,n,current,result) <= getFactorsHelper(n/n,2,current,result) = T(n/n) = T(1)

total cost

T(n) <= T(n/2) + T(n/3) + T(n/4) + ... + T(1)

Solving recursive function

order

I hope this can help you.

posted @ 2017-12-02 22:43  apanda009  阅读(385)  评论(0编辑  收藏  举报