这种题目我首先想到的是采用递归来解决,首先从2到给定的数/2遍历,找出所有的因子,在遍历过程中,递归调用自身,对其中的因子还不是质数的情况下继续找出该数的因子,最后整合。代码如下:
class Solution {
public List<List<Integer>> getFactors(int n) {
ArrayList<ArrayList<Integer>> arrayLists = new ArrayList<>();
return helper(n);
}
public List<List<Integer>> helper(int n) {
List<List<Integer>> helper = new ArrayList<>();
int i = 0;
for (i = 2; i < n / 2; i++) {
if (n % i == 0) {
ArrayList<Integer> integers = new ArrayList<>();
integers.add(i);
integers.add(n / i);
helper.add(integers);
List<List<Integer>> helper1 = helper(n / i);
for (List<Integer> integerList : helper1) {
integerList.add(0, i);
helper.add(integerList);
}
}
}
return helper;
}
}
此段代码有一点就是要
for (List<Integer> integerList : helper1) {
integerList.add(0, i);
helper.add(integerList);
}
这段代码通过遍历返回的所有因子的结果,即后面一个数不断找因子,得到所有的因子,然后在首部插入当前的因子,就得到了整个数的所有因子,要把它加入到结果数组中。
运行虽然说确实可以找到所有的因子,但不满足题目的要求:测试为12:
接下来考虑对得到的结果再进行处理。但是发现很麻烦,最后看了答案:
class Solution {
public List<List<Integer>> getFactors(int n) {
return helper(2, n);
}
public List<List<Integer>> helper(int start, int n) {
List<List<Integer>> helper = new ArrayList<>();
for (int i = start; i <= Math.sqrt(n); i++) {
if (n % i == 0) {
ArrayList<Integer> integers = new ArrayList<>();
integers.add(i);
integers.add(n / i);
helper.add(integers);
List<List<Integer>> helper1 = helper(i, n / i);
for (List<Integer> integerList : helper1) {
integerList.add(0, i);
helper.add(integerList);
}
}
}
return helper;
}
}
其中一个很重要的思想去避免重复:就是在每次迭代除了传入要求的数还传入了开始的位置,这样就可以避免出现重复。究其原因,
首先前面的方法是可以得到所有因子的数组的,而如果继续找后面3开始的因子,就会继续从i=3开始找,所以还会找到4和【2,2】,而如果把之前找的因子当作开始的数传进去,由于这个i递增的,所以后面的数找的因子肯定是大于i的,这样既可以找到所有因子,也可以避免重复。