class Solution:
def getFactors(self, n: int):
res = []
def backtrack(start, target, path):
for i in range(start, int(target ** 0.5) + 1):
if target % i == 0:
res.append(path + [i, target // i])
backtrack(i, target // i, path + [i])
backtrack(2, n, [])
return res
class Solution {
public:
vector<vector<int>> getFactors(int n) {
vector<vector<int>> res;
vector<int> path;
backtrack(2, n, path, res);
return res;
}
void backtrack(int start, int target, vector<int>& path, vector<vector<int>>& res) {
for (int i = start; i * i <= target; ++i) {
if (target % i == 0) {
vector<int> temp = path;
temp.push_back(i);
temp.push_back(target / i);
res.push_back(temp);
path.push_back(i);
backtrack(i, target / i, path, res);
path.pop_back();
}
}
}
};
class Solution {
public List<List<Integer>> getFactors(int n) {
List<List<Integer>> res = new ArrayList<>();
backtrack(2, n, new ArrayList<>(), res);
return res;
}
private void backtrack(int start, int target, List<Integer> path, List<List<Integer>> res) {
for (int i = start; i * i <= target; ++i) {
if (target % i == 0) {
List<Integer> temp = new ArrayList<>(path);
temp.add(i);
temp.add(target / i);
res.add(temp);
path.add(i);
backtrack(i, target / i, path, res);
path.remove(path.size() - 1);
}
}
}
}
var getFactors = function(n) {
const res = [];
function backtrack(start, target, path) {
for (let i = start; i * i <= target; i++) {
if (target % i === 0) {
res.push([...path, i, target / i]);
backtrack(i, target / i, [...path, i]);
}
}
}
backtrack(2, n, []);
return res;
};
Given an integer n
greater than 1, return all possible combinations of its factors (excluding 1 and n
itself) such that the product of the numbers in each combination is n
. Each combination should be a list of integers greater than 1, sorted in ascending order. Do not include duplicate combinations or reorderings. Each factor may be used multiple times in a combination, but the order of factors in a combination must be non-decreasing.
n
(>1)n
n
itself as factors in the combinations[2, 6]
and [6, 2]
are considered the same, only one should appear)
At first glance, the problem looks similar to classic "combination sum" or "subset" problems, but with a twist: instead of summing to a target, we need to multiply to reach n
. The simplest brute-force solution would be to try every possible combination of numbers between 2 and n-1
and check if their product equals n
. However, this would be extremely inefficient, especially for large n
.
To optimize, we notice that:
n
(i.e., numbers that divide n
evenly).n
.
We use a recursive backtracking algorithm to generate all valid factor combinations for n
. Here's how it works step-by-step:
i
divides target
evenly, we know i
is a valid factor.
i
and target / i
to the current combination, and record it as a valid result.
target / i
, starting from i
(to maintain ascending order), and add i
to the combination path.
target
becomes 1 or no further factors can be found (i.e., when i * i > target
).
This approach ensures that:
n
itself as factors
Let's use n = 12
as an example and trace the process:
backtrack(2, 12, [])
i = 2
: 12 % 2 == 0 ⇒ 2 is a factor. Add [2, 6] to results.backtrack(2, 6, [2])
i = 2
: 6 % 2 == 0 ⇒ 2 is a factor. Add [2, 2, 3] to results.backtrack(2, 3, [2, 2])
i = 3
: 6 % 3 == 0 ⇒ 3 is a factor. Add [2, 3, 2] but since we always keep order, only [2, 2, 3] is added.i = 3
: 12 % 3 == 0 ⇒ 3 is a factor. Add [3, 4] to results.backtrack(3, 4, [3])
i = 4
: 12 % 4 == 0 ⇒ 4 is a factor. Add [4, 3], but again, only [3, 4] is kept due to order.
Final result: [[2, 6], [2, 2, 3], [3, 4]]
To solve the Factor Combinations problem, we use a recursive backtracking approach that systematically explores all unique ways to factor n
into integers greater than 1, ensuring combinations are in ascending order and avoiding duplicates. By only considering valid factors at each step and recursing on the quotient, we efficiently generate all solutions without redundant work. This method is both elegant and practical, leveraging mathematical properties of factors and the power of recursion to solve the problem effectively.