一、数组M中取出N个元素的所有组合
const getCombinationsWithRepetition = (array: Array<string>, n: number) => {const result = [] as anyconst currentCombination = [] as anyfunction backtrack(start: number, count: number) {if (count === 0) {result.push(currentCombination.slice()) // 将当前组合添加到结果中return}for (let i = start; i < array.length; i++) {currentCombination.push(array[i]) // 将当前元素添加到当前组合中backtrack(0, count - 1) // 递归调用,继续添加下一个元素currentCombination.pop() // 回溯,移除当前元素以便尝试其他元素}}backtrack(0, n)return result
}const dualViewList = ['abstract', 'claims', 'instructions', 'figures', 'pdf']
const N = 2
const combinations = getCombinationsWithRepetition(dualViewList, N)
这个函数的工作原理如下:
- 定义一个结果数组
result
来存储所有组合。 - 定义一个递归函数
fn
,它接受两个参数:index
(当前正在处理的数组元素的索引)和temp
(当前组合)。 - 如果
temp
的长度等于n
,则将temp
添加到result
中,并返回。 - 否则,从
index
开始遍历数组,对于每个元素,递归调用fn
,将下一个索引和当前组合与新元素合并后的数组作为参数。 - 初始调用
fn
时,索引为0,temp
为空数组。 - 最后返回
result
,它包含所有可能的组合。
二、数组M中取出N个元素的所有组合可重复
function getCombinationsWithRepetition(array, n) { let result = []; let currentCombination = []; function backtrack(start, count) { if (count === 0) { result.push(currentCombination.slice()); // 将当前组合添加到结果中 return; } for (let i = start; i < array.length; i++) { currentCombination.push(array[i]); // 将当前元素添加到当前组合中 backtrack(0, count - 1); // 递归调用,继续添加下一个元素 currentCombination.pop(); // 回溯,移除当前元素以便尝试其他元素 } } backtrack(0, n); return result;
} // 示例
let M = [1, 2, 3];
let N = 2;
let combinations = getCombinationsWithRepetition(M, N);
console.log(combinations);
这个函数的工作原理如下:
- 定义一个结果数组
result
来存储所有组合。 - 定义一个当前组合数组
currentCombination
,用于构建当前的组合。 - 定义一个递归函数
backtrack
,它接受两个参数:start
(当前正在处理的数组元素的起始索引)和count
(还需要添加到当前组合中的元素数量)。 - 如果
count
为0,说明当前组合已经完成,将其添加到结果数组中,并返回。 - 否则,从
start
开始遍历数组,对于每个元素,将其添加到当前组合中,然后递归调用backtrack
函数,继续添加下一个元素。注意,这里我们始终从数组的开始位置(start = 0
)遍历,以允许元素重复。 - 在递归调用返回后,使用
currentCombination.pop()
进行回溯,移除当前元素,以便在下一轮循环中尝试其他元素。 - 初始调用
backtrack
时,start
为0,count
为N。 - 最后返回结果数组
result
,它包含所有可能的组合(包括重复元素)。