題目:
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:
- 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] ]
題解:
求一個數的所有factor,這里我們又想到了DFS + Backtracking, 需要注意的是,factor都是>= 2的,並且在此題里,這個數本身不能算作factor,所以我們有了當n <= 1時的判斷 if(list.size() > 1) add the result to res.
Time Complexity - O(2n), Space Complexity - O(n).
public class Solution { public List<List<Integer>> getFactors(int n) { List<List<Integer>> res = new ArrayList<>(); List<Integer> list = new ArrayList<>(); getFactors(res, list, n, 2); return res; } private void getFactors(List<List<Integer>> res, List<Integer> list, int n, int factor) { if(n <= 1) { if(list.size() > 1) res.add(new ArrayList<Integer>(list)); return; } for(int i = factor; i <= n; i++) { if(n % i == 0) { list.add(i); getFactors(res, list, n / i, i); list.remove(list.size() - 1); } } } }
二刷:
還是使用了一刷的辦法,dfs + backtracking。但遞歸結束的條件更新成了n == 1。 但是速度並不是很快,原因是沒有做剪枝。我們其實可以設置一個upper limit,即當i > Math.sqrt(n)的時候,我們不能繼續進行下一輪遞歸,此時就要跳出了。
Java:
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) { if (n == 1) { if (list.size() > 1) res.add(new ArrayList<>(list)); return; } for (int i = pos; i <= n; i++) { if (n % i == 0) { list.add(i); getFactors(res, list, n / i, i); list.remove(list.size() - 1); } } } }
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); } } } }
Reference:
https://leetcode.com/discuss/51261/iterative-and-recursive-python
https://leetcode.com/discuss/87926/java-2ms-easy-to-understand-short-and-sweet
https://leetcode.com/discuss/58828/a-simple-java-solution
https://leetcode.com/discuss/72224/my-short-java-solution-which-is-easy-to-understand
https://leetcode.com/discuss/82087/share-bit-the-thought-process-short-java-bottom-and-top-down