Link do tópico: 77. Combinação
Descrição do tópico: Dados dois inteiros n e k, retorne todas as combinações possíveis de k números em 1 ... n.
Exemplo:
输入: n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
Idéia: solução convencional, recursão + retrocesso, use um subscrito startIndex para indicar o ponto de partida da pesquisa atual, enquanto a pesquisa registrará o valor atual neste caminho, após pesquisar uma rodada de respostas, retroceder, excluir o último valor e mude o caminho Continue procurando.
Código:
class Solution {
public void dfs(int n,int startIndex,List<Integer> list,List<List<Integer>> ans,int k){
if(k==list.size()){
List<Integer> list1=new ArrayList<>(list);
ans.add(list1);
return ;
}
for(int i=startIndex;i<=n;i++){
list.add(i);
dfs(n,i+1,list,ans,k);
list.remove(list.size()-1);
}
}
public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> ans=new ArrayList<List<Integer>>();
if(n<k||k<=0){
return ans;
}
List<Integer> list=new ArrayList<>();
dfs(n,1,list,ans,k);
return ans;
}
}
Tópicos semelhantes: 46. Permutação completa +47. Permutação completa II. Para obter
mais detalhes , consulte 39.
Descrição do problema de soma de combinação : Dada uma matriz de candidatos sem elementos repetidos e uma meta de número de destino, encontre todos os candidatos que podem fazer o número combinação de destino de soma.
Os números nos candidatos podem ser selecionados repetidamente sem limitação.
Exemplo:
输入:candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]
输入:candidates = [2,3,5], target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
intervalo de dados:
1 <= candidates.length <= 30
1 <= candidates[i] <= 200
candidate 中的每个元素都是独一无二的。
1 <= target <= 500
Idéia: Semelhante à idéia acima, exceto que cada elemento aqui pode ser reutilizado, portanto, ao pesquisar, comece a partir do nó atual.
Código:
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<Integer> list=new ArrayList<>();
List<List<Integer>> ans=new ArrayList<List<Integer>>();
dfs(candidates,0,list,ans,target);
return ans;
}
public void dfs(int nums[],int startIndex,List<Integer> list,List<List<Integer>> ans,int target){
if(target<0) return;
if(target==0){
ans.add(new ArrayList<>(list));
return ;
}
for(int i=startIndex;i<nums.length;i++){
list.add(nums[i]);
dfs(nums,i,list,ans,target-nums[i]);//可以重复利用每个元素,因此还是从当前位置开始搜
list.remove(list.size()-1);
}
}
}
Link do título: 40. Combination Sum II
Title Description: Dada uma matriz de candidatos e uma meta de número alvo, descubra todas as combinações de candidatos que podem fazer a soma de alvos de números.
Cada número em candidatos só pode ser usado uma vez em cada combinação.
- Todos os números (incluindo o número de destino) são inteiros positivos.
- O conjunto de soluções não pode conter combinações repetidas.
Exemplo:
输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
[1,2,2],
[5]
]
Idéia: Um número só pode ser usado uma vez, o método é ordenar a ordem primeiro e depois continuar diretamente se dois adjacentes forem iguais para evitar a repetição do registro da resposta.
class Solution {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Arrays.sort(candidates);
List<Integer> list=new ArrayList<>();
List<List<Integer>> ans=new ArrayList<List<Integer>>();
dfs(candidates,target,list,ans,0);
return ans;
}
public void dfs(int []nums,int target,List<Integer> list,List<List<Integer>> ans,int startIndex){
if(target<0) return;
if(target==0){
List<Integer> list1=new ArrayList<>(list);
ans.add(list1);
return;
}
for(int i=startIndex;i<nums.length;i++){
if(i>startIndex&&nums[i] == nums[i-1]) continue;//避免出现重复情况
list.add(nums[i]);
dfs(nums,target-nums[i],list,ans,i+1);
list.remove(list.size()-1);
}
}
}