Algorithm
[Algo] 백준 2800 괄호 제거 JAVA
조핑구
2024. 5. 8. 13:47
문제 바로가기 : https://www.acmicpc.net/problem/2800
메모리 : 26332KB
시간 : 280ms
언어 : Java 11
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;
import java.util.TreeSet;
public class Main {
static int[] bracket;
static boolean[] check;
static int idx, cnt;
static TreeSet<String> anslist = new TreeSet<>();
static String str;
public static <T> void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
str = br.readLine();
bracket = new int[str.length()];
cnt = 0;
idx = 1;
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == '(') {
cnt++;
bracket[i] = idx;
stack.add(idx++);
} else if (str.charAt(i) == ')') {
bracket[i] = stack.pop();
}
}
check = new boolean[cnt + 1];
dfs(1);
anslist.remove(str);
StringBuilder sb = new StringBuilder();
for (String s : anslist) {
sb.append(s).append("\n");
}
System.out.println(sb);
}
private static void dfs(int idx) {
if (idx > cnt + 1)
return;
String tmp = "";
for (int i = 0; i < str.length(); i++) {
if (bracket[i] != 0 && check[bracket[i]]) {
continue;
} else {
tmp += str.charAt(i);
}
}
anslist.add(tmp);
for (int i = idx; i <= cnt; i++) {
check[i] = true;
dfs(i + 1);
check[i] = false;
}
}
}
- stack으로 괄호에 몇번째 괄호인지 번호를 메긴다.
- 여는괄호 ( 에 시작번호 idx 를 할당해서 붙여주고 이를 스택에 넣는다. 이는 먼저 열린 괄호가 나중에 닫히는 성질을 이용하기 위해서이다.
- 닫는괄호 ) 가 나오면 스택에서 가장 위에 있는 idx를 꺼내 붙여준다. 상기하였듯 최근에 열린 괄호가 가장 빨리 닫히기 때문이다.
- 괄호의 개수로 조합을 만들어 어떤 괄호를 제거할 것인지 경우의 수를 계산한다.
- 이때 제거하기로 한 괄호는 check 배열에 표시되고, 해당 괄호가 bracket에 표시된 그 번호인지 검사해준다.
- 만든 문자열을 TreeSet에 넣거 중복제거+사전순정렬의 효과를 누린다.