LeetCode 254. Factor Combinations(因式分解)

来源:互联网 发布:永强集团淘宝店是什么 编辑:程序博客网 时间:2024/04/30 04:49

原题网址: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: 

  1. Each combination's factors must be sorted ascending, for example: The factors of 2 and 6 is [2, 6], not [6, 2].
  2. You may assume that n is always positive.
  3. 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]]
思路:深度优先搜索。

public class Solution {    private void find(List<Integer> factors, int target, List<List<Integer>> results) {        // System.out.printf("factors=%s\n", factors);        if (target == 1) {            if (!factors.isEmpty()) {                List<Integer> result = new ArrayList<>(factors.size());                result.addAll(factors);                results.add(result);            }            return;        }        int min = factors.isEmpty()? 2 : factors.get(factors.size()-1);        int max = factors.isEmpty()? target/2 : target;        for(int f = min; f <= max; f ++) {            if (target % f != 0) continue;            factors.add(f);            find(factors, target/f, results);            factors.remove(factors.size()-1);        }    }    public List<List<Integer>> getFactors(int n) {        List<List<Integer>> results = new ArrayList<>();        find(new ArrayList<>(), n, results);        return results;    }}

优化:关键在于i*i<=n,可以大幅提升性能。

public class Solution {    private void find(int from, int n, List<Integer> factors, List<List<Integer>> results) {        for(int i=from; i*i<=n; i++) {            if (n % i == 0) {                factors.add(i);                find(i, n/i, factors, results);                factors.remove(factors.size()-1);            }        }        if (!factors.isEmpty()) {            factors.add(n);            results.add(new ArrayList<>(factors));            factors.remove(factors.size()-1);        }    }    public List<List<Integer>> getFactors(int n) {        List<List<Integer>> results = new ArrayList<>();        find(2, n, new ArrayList<>(), results);        return results;    }}

由于ArrayList较慢,如果固定分配空间可以进一步提升性能。

public class Solution {    private void find(int from, int n, int[] factors, int len, List<List<Integer>> results) {        for(int i=from; i*i<=n; i++) {            if (n % i == 0) {                factors[len] = i;                find(i, n/i, factors, len+1, results);            }        }        if (len > 0) {            factors[len] = n;            Integer[] f = new Integer[len+1];            for(int i=0; i<=len; i++) f[i] = factors[i];            results.add(Arrays.asList(f));        }    }    public List<List<Integer>> getFactors(int n) {        int p = 0;        for(int i=1; i<=n; p++, i*=2);        List<List<Integer>> results = new ArrayList<>();        find(2, n, new int[p], 0, results);        return results;    }}

0 0