【Leetcode】254. Factor Combinations
题面
https://leetcode.com/problems/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]
]
第一遍:
有重复解,大概知道是因为分解到后面把数字小的带进来了,但是找不到很好的办法去重。
class Solution {
public List<List<Integer>> getFactors(int n) {
return helper(n);
}
public List<List<Integer>> helper(int n) {
List<List<Integer>> result = new LinkedList<>();
for (int i = 2; i <= n ; i++) {
if (i > n/i) {
break;
}
if ( n%i == 0 ) {
List<List<Integer>> current = helper(n/i);
List<Integer> cur = new LinkedList<>();
cur.add(n/i);
current.add(0,cur);
for (int j = 0; j < current.size(); j++) {
current.get(j).add(i);
result.add(current.get(j));
}
}
}
return result;
}
}
Input: 12
Output:
[[6,2],[3,2,2],[4,3],[2,2,3]]
Expected:
[[2,6],[3,4],[2,2,3]]
第二遍:
主要就是去重,想到只要保证每次分解出来的因子比自己大就不会重复了,所有的结果list的数都是从大到小的排列,所以每次的因子要从上一次的因子开始,就能保证不会有重复。
class Solution {
public List<List<Integer>> getFactors(int n) {
return helper(n, 1);
}
public List<List<Integer>> helper(int n, int start) {
List<List<Integer>> result = new LinkedList<>();
for (int i = 2; i <= n ; i++) {
if (i > n/i) {
break;
}
if (i < start) {
continue;
}
if ( n%i == 0 ) {
List<List<Integer>> current = helper(n/i, i);
List<Integer> cur = new LinkedList<>();
cur.add(n/i);
current.add(0,cur);
for (int j = 0; j < current.size(); j++) {
current.get(j).add(i);
result.add(current.get(j));
}
}
}
return result;
}
}
通过测试,77%的速度。
第三遍:
优化代码,把开始的两个if判断放到for循环的边界里面去。
class Solution {
public List<List<Integer>> getFactors(int n) {
return helper(n, 2);
}
public List<List<Integer>> helper(int n, int start) {
List<List<Integer>> result = new LinkedList<>();
for (int i = start; i <= (int)Math.sqrt(n); i++) {
if (n%i == 0) {
List<List<Integer>> current = helper(n/i, i);
List<Integer> cur = new LinkedList<>();
cur.add(n/i);
current.add(0,cur);
for (int j = 0; j < current.size(); j++) {
current.get(j).add(i);
result.add(current.get(j));
}
}
}
return result;
}
}
总结:
- 如何去重复,总体来说排序是最简单的办法,用大小判断来去重,保证每次后续的因子大于本身。
- 这道题目要求所有的因子,而非只有质因子,比如2*6的6是需要加进去的,所有需要每一次都把当前的因子加进去。如果只要求质因子,就不加了。