모든 코드는 ArrayList<Integer[]>
인 result를 반환하도록 구현하였다.
result 내에는 n과 r이 주어졌을 때, 모든 경우를 저장한다.
(저장하지 않고, 경우를 그대로 출력하는 것이 더 쉽지만, 재귀의 flow에 익숙해질 수 있게 result를 return하는 코드를 짜봤다.)
ArrayList<Integer[]> result
: 전체 경우의 수를 저장할 ArrayListarr[]
: 순열을 실행할 배열(arr.length
= n
)r
: n 개 중 뽑힐 갯수out[]
: 뽑힌 r개의 값을 저장하는 배열 (하나의 경우만 저장)visited[]
: 중복해서 뽑지 않기 위해 방문했는지를 체크하는 배열depth
: DFS의 깊이, out[]
에 들어간 숫자의 길이ArrayList<Integer[]>
에 저장되어야 하므로, out[]
배열을 깊은 복사해서 새로운 배열(newArr
)로 만든 후, ArrayList에 추가해야 한다.out[]
에 들어간 숫자의 길이인 depth
가 뽑으려는 갯수인 r
과 같아지면, 하나의 경우가 완성되는 것이므로 result에 추가하고 return한다.visited[i] = false
를 해준다.arr[i]
가 다른 경우에도 사용될 수 있으므로 public static void main(String[] args) {
Integer[] arr = {1, 2, 3, 4, 5};
int r = 3;
ArrayList<Integer[]> output = permutation(new ArrayList<>(), arr, new Integer[r], new boolean[arr.length], 0, r);
output.forEach(e -> System.out.println(Arrays.toString(e)));
}
public ArrayList<Integer[]> permutation(ArrayList<Integer[]> result, Integer[] arr, Integer[] out, boolean[] visited, int depth, int r) {
if (depth == r) {
result.add(out);
return result;
}
for (int i = 0; i < arr.length; i++) {
if (!visited[i]) {
visited[i] = true;
Integer[] newArr = Arrays.copyOf(out, out.length);
newArr[depth] = arr[i];
result = permutation(result, arr, newArr, visited, depth + 1, r);
visited[i] = false;
}
}
return result;
}
중복 순열은 중복을 체크하지 않는다는 것만 제외하곤, 순열과 동일하다.
public static void main(String[] args) {
Integer[] arr = {1, 2, 3, 4, 5};
int r = 3;
ArrayList<Integer[]> output = permutation(new ArrayList<>(), arr, new Integer[r], 0, r);
output.forEach(e -> System.out.println(Arrays.toString(e)));
}
public ArrayList<Integer[]> permutation(ArrayList<Integer[]> result, Integer[] arr, Integer[] out, int depth, int r)
if (depth == r) {
result.add(out);
return result;
}
for (int i = 0; i < arr.length; i++) {
Integer[] newArr = Arrays.copyOf(out, out.length);
newArr[depth] = arr[i];
result = permutation(result, arr, newArr, depth + 1, r);
}
return result;
}
public static void main(String[] args){
Integer[] arr = {1, 2, 3,4,5};
int r = 4;
ArrayList<Integer[]> output = combination(new ArrayList<>(), arr, new Integer[r], 0, 0, r);
output.forEach(e -> System.out.println(Arrays.toString(e)));
}
public ArrayList<Integer[]> combination(ArrayList<Integer[]> result, Integer[] arr, Integer[] out, int start, int depth, int r){
if(depth == r){
result.add(out);
return result;
}
for(int i=start; i<arr.length; i++){
Integer[] newArr = Arrays.copyOf(out, out.length);
newArr[depth] = arr[i];
result = combination(result, arr, newArr, i+1, depth+1, r);
}
return result;
}
[참고]
순열
조합
https://minhamina.tistory.com/38
https://minhamina.tistory.com/37
순열, 중복순열, 조합, 중복조합 등
https://velog.io/@khyunjiee/TIL-%EC%9E%AC%EA%B7%80%EB%A1%9C-%ED%91%B8%EB%8A%94-%EC%88%9C%EC%97%B4%EA%B3%BC-%EC%A1%B0%ED%95%A9
https://bcp0109.tistory.com/15
https://velog.io/@gandi0330/JAVA-%EC%88%9C%EC%97%B4-%EC%A4%91%EB%B3%B5%EC%88%9C%EC%97%B4-%EC%A1%B0%ED%95%A9-%EC%A4%91%EB%B3%B5-%EC%A1%B0%ED%95%A9-%EA%B5%AC%ED%98%84
https://cocoon1787.tistory.com/686