class Solution {
public List<List<Integer>> answer = new ArrayList<>();
public List<Integer> list = new ArrayList<>();
public void combination(int[] arr, boolean[] visited, int start, int depth, int k){
if(depth == k){
for(int i = 0 ; i < arr.length; i++){
if(visited[i]) list.add(arr[i]);
}
answer.add(list);
list = new ArrayList<>();
return;
}
for(int i = start ; i < arr.length ; i++){
if(!visited[i]){
visited[i] = true;
combination(arr, visited, i+1, depth+1, k);
visited[i] = false;
}
}
}
public List<List<Integer>> combine(int n, int k) {
int[] arr = new int[n];
for(int i = 0 ; i < n ; i++) arr[i] = i+1;
boolean[] visited = new boolean[n];
combination(arr, visited, 0, 0, k);
return answer;
}
}
서로 다른 n 개 중 순서없이 r 개를 뽑는 것 , 일종의 dfs 를 이용한 재귀이자 백트래킹
public void combination(int[] arr, boolean[] visited, int start, int depth, int r){
if(depth == r) {
for(int i = 0 ; i < arr.length ; i++){
if(visited[i]) System.out.print(arr[i]+" ")
}
}
return;
}
for(int i = start ; i < arr.length ; i++){
if(!visited[i]){
visited[i] = true;
combination(arr, visited, i+1, depth+1, r);
//현재 원소보다 뒤의 원소 탐색 -> i+1, depth+1
visited[i] = false;
}
}
}
arr = [1,2,3,4]
//2개 조합
[1,2]
[1,3]
[1,4]
[2,3]
[2,4]
[3,4]
=> 6개
서로 다른 n 개 중 순서없이, 중복이 가능하게 r 개를 뽑는 것
public void combinationWithDuplication(int[] arr, int[] out, int start, int depth, int r){
if(depth == r){
//선택된 원소들이 저장된 배열 out 추출
for(int num : out) System.out.println(num);
return;
}
for(int i = 0 ; i < arr.length; i++){
out[depth] = arr[i];
combinationWithDuplication(arr, out, i, depth+1, r);
//현재 원소를 깊이에 맞게 저장해두고
//중복 가능하기 때문에 현재 원소부터 뒤의 원소까지 탐색 -> i, depth+1
}
}
arr = [1,2,3,4]
//2개 조합
[1,1]
[1,2]
[1,3]
[1,4]
[2,2]
[2,3]
[2,4]
[3,3]
[3,4]
[4,4]
=> 10개