백준 1010 문제를 풀며 의문이 들어 기록
처음 문제를 보며 최대 N개의 다리를 놓을 수 있으며 모든 경우의 수를 찾는 것이고 다리가 겹치는 부분은 존재하지 않아야 한다는 것은 알고 있었다
때문에 재귀를 이용해 숫자를 하나씩 늘리며 앞 숫자보다 크지 않는 경우의 조합을 구현하려다 실패
구글링 중에 단순히 조합을 적용해 푸는 것을 확인
def permutation(arr, r):
arr = sorted(arr)
used = [0 for _ in range(len(arr))]
def generate(chosen, used):
if len(chosen) == r:
print(chosen)
return
for i in range(len(arr)):
if not used[i]:
chosen.append(arr[i])
used[i] = 1
generate(chosen, used)
used[i] = 0
chosen.pop()
generate([], used)
package algorithm;
import java.util.ArrayList;
import java.util.List;
public class expri {
static int answer = 0;
static List<Integer> finalResult = new ArrayList<>();
public static void main(String[] args) {
int[] arr = {1,2,3};
int[] result = new int[arr.length];
boolean[] visited = new boolean[arr.length];
for(int i = 0; i<arr.length; i++) {
permutation(arr, result, visited, 0, i+1);
}
}
static void permutation(int[] arr, int[] result, boolean[] visited, int depth, int r) {
if(depth == r) {
for(int i =0; i<r; i++) {
System.out.print(result[i]+" ");
}
System.out.println();
return;
}
for(int i =0; i<arr.length; i++) {
if(!visited[i]) {
visited[i] = true;
result[depth] = arr[i];
permutation(arr, result, visited, depth+1,r);
visited[i] = false;
}
}
}
}
main
함수에서 목표하는 순열 길이를 permutation
함수에 보내고 방문 유무를 판단해 목표하는 순열 길이에 따른 순열을 저장한다main 반복문
목표하는 순열 길이 1인 경우,
permutation 반복
return
목표하는 순열 길이 2인 경우,
permutation 반복
return
목표하는 순열 길이 3인 경우,
permutation 반복
return
백트래킹 사용하는 이유는 유망하지 않은 경우 다시 되돌아와야되기 때문
ex) 1 => 2 => 3 후에 함수가 종료된다면 1 => 3 => 4 를 진행하고 이 후에 1 => 4 => 2처럼 되돌아오며 방문 표시를 방문하지 않은 것으로 바꾸는 이유
def combinations(arr,r):
for i in range(len(arr)):
if r == 1:
yield [arr[i]]
else:
for next in combinations(arr[i+1:],r-1):
yield [arr[i]] + next
for combi in combinations([1,2,3,4],3):
print(combi)
조합의 경우 순열과의 차이점은 순서가 달라도 구성이 같으면 같은 것으로 취급한다
때문에 여기서 중요한 것은 순열과 로직은 유사하게 진행되지만 시작 지점
을 정의해주고 시작 지점
이후부터 반복을 진행한다
public class Main {
static void comb(int[] arr, boolean[] visited, int n, int depth, int start){
if (depth == n) {
for(int i = 0; i < arr.length; i++){
if(visited[i]){
System.out.print(arr[i] + " ");
}
}
System.out.println();
return;
}
for(int i = start; i < arr.length; i++){
visited[i] = true;
comb(arr, visited, n, depth+1, i+1);
visited[i] = false;
}
}
public static void main(String[] args) throws Exception {
int[] arr = {1, 2, 3, 4};
boolean[] visited = new boolean[4];
for(int i = 0; i < 4; i++){
comb(arr, visited, i+1, 0, 0);
}
}
}
1
2
3
4
1 2
1 3
1 4
2 3
2 4
3 4
1 2 3
1 2 4
1 3 4
2 3 4
1 2 3 4