문제
https://programmers.co.kr/learn/courses/30/lessons/60058
코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| private static final Character LEFT = '('; private static final Character RIGHT = ')';
public String solution(String p) { String answer = getDivide(p); return answer; }
private String getDivide(String w) { if (w.isEmpty()) { return w; }
String[] uAndv = getUAndV(w); String u = uAndv[0]; String v = uAndv[1];
if (!isPerfectBracket(u)) { return createPerfectBracket(u, v); }
return u + getDivide(v); }
private String[] getUAndV(String w) { StringBuilder sb = new StringBuilder(); char[] tochar = w.toCharArray(); Stack<Character> stack = new Stack<>(); char popChar = (tochar[0] == LEFT) ? RIGHT : LEFT;
for (char ch : tochar) { if (ch == popChar) { stack.pop(); sb.append(popChar); } else { sb.append(stack.push(ch)); }
if (stack.isEmpty()) { break; } }
String[] uAndv = new String[2]; uAndv[0] = sb.toString(); uAndv[1] = new String(tochar, uAndv[0].length(), tochar.length - uAndv[0].length());
return uAndv; }
private boolean isPerfectBracket(String u) { int sum = 0; for (int i = 0; i < u.length(); i++) { sum += (u.charAt(i) == LEFT) ? +1 : -1;
if (sum < 0) { break; } }
return sum == 0; }
private String createPerfectBracket(String u, String v) { StringBuilder str = new StringBuilder();
str.append(LEFT); str.append(getDivide(v)); str.append(RIGHT);
char[] newU = u.substring(1, u.length() -1).toCharArray(); str.append(getChange(newU));
return str.toString(); }
private char[] getChange(char[] newU) { for (int i = 0; i < newU.length; i++) { newU[i] = (newU[i] == LEFT) ? RIGHT : LEFT; }
return newU; }
|
흐름
- 입력이 빈 문자열인 경우, 빈 문자열을 반환합니다.
- 문자열 w를 두 “균형잡힌 괄호 문자열” u, v로 분리합니다.
단, u는 “균형잡힌 괄호 문자열”로 더 이상 분리할 수 없어야 하며, v는 빈 문자열이 될 수 있습니다.
- 문자열 u가 “올바른 괄호 문자열” 이라면 문자열 v에 대해 1단계부터 다시 수행합니다.
- 수행한 결과 문자열을 u에 이어 붙인 후 반환합니다.
- 문자열 u가 “올바른 괄호 문자열”이 아니라면 아래 과정을 수행합니다.
- 빈 문자열에 첫 번째 문자로 ‘(‘를 붙입니다.
- 문자열 v에 대해 1단계부터 재귀적으로 수행한 결과 문자열을 이어 붙입니다.
- ‘)’를 다시 붙입니다.
- u의 첫 번째와 마지막 문자를 제거하고, 나머지 문자열의 괄호 방향을 뒤집어서 뒤에 붙입니다.
- 생성된 문자열을 반환합니다.
결과
번호 |
속도 |
테스트 1 |
통과 (32.01ms, 55.5MB) |
테스트 2 |
통과 (1.42ms, 52.3MB) |
테스트 3 |
통과 (30.81ms, 55.3MB) |
테스트 4 |
통과 (30.93ms, 52.9MB) |
테스트 5 |
통과 (30.16ms, 55.5MB) |
테스트 6 |
통과 (29.55ms, 55.3MB) |
테스트 7 |
통과 (35.55ms, 53MB) |
테스트 8 |
통과 (29.41ms, 55.2MB) |
테스트 9 |
통과 (28.63ms, 53.6MB) |
테스트 10 |
통과 (30.95ms, 54.9MB) |
테스트 11 |
통과 (30.81ms, 55.9MB) |
테스트 12 |
통과 (28.73ms, 55.3MB) |
테스트 13 |
통과 (30.50ms, 55.7MB) |
테스트 14 |
통과 (38.62ms, 53.5MB) |
테스트 15 |
통과 (31.72ms, 53.5MB) |
테스트 16 |
통과 (31.20ms, 55MB) |
테스트 17 |
통과 (30.63ms, 55.2MB) |
테스트 18 |
통과 (33.95ms, 55.4MB) |
테스트 19 |
통과 (31.25ms, 53.6MB) |
테스트 20 |
통과 (33.02ms, 55.5MB) |
테스트 21 |
통과 (33.70ms, 53.5MB) |
테스트 22 |
통과 (33.13ms, 53.5MB) |
테스트 23 |
통과 (32.43ms, 53MB) |
테스트 24 |
통과 (31.24ms, 55.9MB) |
테스트 25 |
통과 (33.63ms, 56MB) |
테스트 케이스
1 2 3 4 5 6 7 8 9
| assertEquals("(()())()", test.solution("(()())()")); assertEquals("()", test.solution(")(")); assertEquals("()(())()", test.solution("()))((()")); assertEquals("(((())))", test.solution(")()()()(")); assertEquals("()()((()))", test.solution("))()))((((")); assertEquals("()", test.solution("()")); assertEquals("()()()()()()((()))", test.solution("()()()()()()((()))")); assertEquals("((((())())))()(())", test.solution("((((())()))))))(((")); assertEquals("(((()())())())((()))", test.solution("))))((((((()())()))("));
|