728x90
코딩 테스트 준비를 하다 순열, 조합 문제가 꽤 나와서
헷갈리지 않게 정리해보려고 한다.
조합
조합은 말 그대로 n개 중 r개의 조합을 말한다. 따라서 순서가 있어선 안 된다.
조합은 순열과 다르게 순서가 있어서는 안 되기 때문에 이를 위한 장치가 중요하다.
먼저 코드를 보자.
package AlgorithmNote.NumberTheory;
import java.util.*;
public class Combination {
public static void combination(int[] arr,int[]output,boolean[] visited, int start,int n,int r){
if(r==0){
System.out.println(Arrays.toString(output));
return;
}
for(int i=start;i<n;i++){
visited[i]=true;
output[r-1]=arr[i];
combination(arr,output,visited,i+1,n,r-1);
visited[i]=false;
}
}
public static void main(String[] args){
int[] nums=new int[]{1,2,3};
int r=3;
combination(nums,new int[r],new boolean[nums.length],0,nums.length,r);
}
}
//실행 결과
[2, 1]
[3, 1]
[3, 2]
- arr : n개의 수를 담은 배열이다.
- output : 없어도 되지만 조합의 결과를 담을 output 함수이다.
- 길이는 r과 같아야 한다.
- visited : 중복을 막기 위한 boolean 배열이다.
- 길이는 n과 같아야 한다.
- start : 이것이 바로 순서를 없애주는 장치이다.
- n : arr 배열의 크기이다.
- r : n개 중 선택할 조합 원소의 개수이다.
이 과정을 보여줄 그림은 아래와 같다.
start라는 정수는 배열 중 방문한 원소의 인덱스를 말하며,
for 문 내부에서 r의 크기를 감소시키며 combination() 메소드를 재귀적으로 호출할 때,
start+1을 해줌으로써 다음 for 문에서 start+1부터 시작하게 한다.
결과적으로 start는 방문한 원소를 다시 방문하지 못하게 함으로써 순서를 없애주는 역할을 하는 것이다.
순열
순열은 조합과는 다르게 n개 중 r개의 순열을 뽑는다. 따라서 순서가 있어야 한다.
순열은 순서가 있어야 하기 때문에 위의 start같은 장치가 없어도 된다.
코드를 먼저 보자.
package AlgorithmNote.NumberTheory;
import java.util.*;
public class Permutation {
public static void permutation(int[] arr,int[] out,boolean[] visited, int depth, int r){
if(depth==r){
System.out.println(Arrays.toString(out));
return;
}
for(int i=0;i<arr.length;i++){
if(!visited[i]){
visited[i]=true;
out[depth]=arr[i];
permutation(arr,out,visited,depth+1,r);
visited[i]=false;
}
}
}
public static void main(String[] args){
int[] arr={1,2,3};
int r=2;
permutation(arr,new int[r],new boolean[arr.length],0,r);
}
}
//실행 결과
[1, 2]
[1, 3]
[2, 1]
[2, 3]
[3, 1]
[3, 2]
위 조합과 다른 depth만 살펴보자.
- depth : 깊이를 말하며 순열 결과 배열(out)에 몇 번째 원소까지 담았는지 알려준다.
그림처럼 순열은 start를 따로 지정해주지 않았기 때문에
방문했던 1과 2가 out 배열에 담길 수 있는 것을 볼 수 있다.
마무리
정리하면서 백트래킹과 재귀에 대해서도 자세하게 공부해야 함을 느꼈다.
잘못된 정보에 대한 피드백은 환영입니다. 감사합니다.
728x90
'Algorithm&Data Structure' 카테고리의 다른 글
[Algorithm] Java 재귀, 스택 프레임 (0) | 2023.08.25 |
---|---|
[Algorithm] 정수론 및 조합론(백준 2981,2004번) (0) | 2023.01.25 |
[Algorithm] Python 집합 유형 (0) | 2023.01.10 |
[Algorithm] 백준 정렬 파트 (2108,18870) (1) | 2022.12.22 |
[Algorithm] 탐색 알고리즘 DFS/BFS (0) | 2022.12.11 |