1. 程式人生 > >254 Factor Combinations

254 Factor Combinations

ren 都是 first arp put cost write output hang

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 combinations 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

技術分享圖片

I hope this can help you.

254 Factor Combinations