서로 다른 n개중에 r개를 선택하여 정렬하는 경우의 수
static boolean[] visited;
static int[] result;
public static void main(String[] args) {
int[] arr = {1, 2, 3};
int r = 2;
visited = new boolean[arr.length];
result = new int[r];
permutation(arr, 0, r);
}
public static void permutation(int[] origin, int depth, int r) {
if (depth == r) {
for (int i = 0; i < result.length; i++) {
System.out.print(result[i] + " ");
}
System.out.println();
return;
}
for (int i = 0; i < origin.length; i++) {
if (!visited[i]) {
visited[i] = true;
result[depth] = i;
permutation(origin, depth + 1, r);
visited[i] = false;
}
}
}
재귀의 2step을 보면, 이미 선택된 숫자들은 쳐다보지 않는다.
서로 다른 n개중에 중복이 가능하게 r개를 선택하여 정렬하는 경우의 수
static int[] result;
public static void main(String[] args) {
int[] arr = {1, 2, 3};
int r = 3;
result = new int[r];
permutation(arr, 0, r);
}
public static void permutation(int[] origin, int depth, int r) {
if (depth == r) {
for (int i = 0; i < result.length; i++) {
System.out.print(result[i] + " ");
}
System.out.println();
return;
}
for (int i = 0; i < origin.length; i++) {
result[depth] = i;
permutation(origin, depth + 1, r);
}
}
서로 다른 n개에서 r개를 뽑는 방법의 수(순서 상관 없음)
static boolean[] visited;
static int[] result;
public static void main(String[] args) {
int[] arr = {1, 2, 3};
int r = 2;
visited = new boolean[arr.length];
result = new int[r];
permutation(arr, 0, 0, r);
}
public static void permutation(int[] origin, int depth, int start, int r) {
if (depth == r) {
for (int i = 0; i < result.length; i++) {
System.out.print(result[i] + " ");
}
System.out.println();
return;
}
for (int i = start; i < origin.length; i++) {
if (!visited[i]) {
visited[i] = true;
result[depth] = origin[i];
permutation(origin, depth + 1, i + 1, r);
visited[i] = false;
}
}
}
언뜻보면 순열과 비슷하지만, 이미 지나온 값은 탐색하지 않는다는 차이가 있음.
다음 재귀의 start는 현재 값(인덱스)의 + 1이다.
서로 다른 n개에서 중복이 가능하게 r개를 뽑는 방법의 수
static int[] result;
public static void main(String[] args) {
int[] arr = {1, 2, 3};
int r = 2;
result = new int[r];
permutation(arr, 0, 0, r);
}
public static void permutation(int[] origin, int depth, int start, int r) {
if (depth == r) {
for (int i = 0; i < result.length; i++) {
System.out.print(result[i] + " ");
}
System.out.println();
return;
}
for (int i = start; i < origin.length; i++) {
result[depth] = origin[i];
permutation(origin, depth + 1, i, r);
}
}
중복 순열과 동일해 보이지만 [1, 2, 1]이 가능한 중복순열과 달리 이미 지난 수는 선택하지 않는게 중복 조합 특징.
자기 자신을 다음 재귀에 한번 더 선택할 수 있다고 생각하면 쉬움.