해석과 풀이는 개인적인 부분이기 때문에 참고만 하시길 바랍니다. 다른 접근 및 풀이는 언제나 환영합니다. 댓글로 남겨주세요.
1. 문제
Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.
An input string is valid if:
- Open brackets must be closed by the same type of brackets.
- Open brackets must be closed in the correct order.
- Every close bracket has a corresponding open bracket of the same type.
Example 1:
Input: s = "()"
Output: true
Example 2:
Input: s = "()[]{}"
Output: true
Example 3:
Input: s = "(]"
Output: false
* parenthesis[ pəˈrenθəsɪs ] 삽입어구, bracket (복수형 parenthesises)
* brace[ breɪs ] 버팀대, 대비를 하다, 버팅기다, 중괄호
2. 해석
주어진 문자열에서 괄호 '(' 와 중괄호 '{', 대괄호 '['가 나올 경우 열린 괄호는 동일한 괄호로 닫혀야하고, 닫힐 때 순서가 맞아야 하며, 닫는 괄호에는 동일한 열린 괄호가 있다는 것이다.
모두 올바르게 열고 닫는 짝이 맞을 경우 해당 문자열은 유효하다 true, 아니면 false를 반환한다.
3. 나의 풀이
- 주어진 문자열(s)를 반복문으로 돌리면서 괄호 하나씩 가져오고
- 하나씩 가져온 괄호를 빈 문자열 tmp에 담아둔다.
- 담아둘 때 닫히는 괄호가 등장하면 동일한 열린 괄호가 tmp의 마지막 문자열에 있는지 확인한다.
- 동일한 열린 괄호가 있으면 있으면 tmp에서 마지막 문자열을 제거한다. (즉, (), {}, [] 짝으로 나올 경우 짝을 제거)
- 최종 tmp에 괄호가 남아 있다면 해당 주어진 문자열(s)은 유효하지가 않다.
package leetCode;
class Solution {
public boolean isValid(String s) {
boolean rtn = false;
String tmp = "";
for(int i=0; i<s.length(); i++) {
char chr = s.charAt(i);
int size = tmp.length();
if(size == 0) tmp += chr;
if(size > 0) {
String lastStr = tmp.substring(size-1);
// 닫히는 괄호가 나올경우 tmp의 마지막 문자열을 비교
if(
(chr == ']' && lastStr.equals("[")) ||
(chr == '}' && lastStr.equals("{")) ||
(chr == ')' && lastStr.equals("("))
) {
tmp = tmp.substring(0, size-1);// 마지막 문자열의 열린 괄호를 제거
}else {
tmp += chr;
}
}
}
if(tmp.length() == 0){
rtn = true;
}
return rtn;
}
}
4. leetCoder의 접근 및 풀이
- Stack의 특성을 사용하여 (언제나 그렇듯 아주) 쉽게 문제를 해결하였다.
- 스택에 대해 짚고 넘어갈 부분은 Stack 클래스의 정리 및 활용을 참고하길 바란다.
- 빈 스택객체를 만들어 열린 괄호가 나오면 이에 매칭되는 닫는 괄호를 담다가(push)
- 닫는 괄호가 나올 경우 바로 직전에 담았던 괄호를 꺼내어(pop) 동일한 닫는 괄호인지 비교하여 아닐 경우 유효한 문자열이 아니라고 반환한다. 끝~
class Solution {
public boolean isValid(String s) {
Stack<Character> stack = new Stack<Character>();
for (char c : s.toCharArray()) { // loop
// 열린 괄호에 매칭되는 닫히는 괄호를 스택에 담는다.
if (c == '(')
stack.push(')');
else if (c == '{')
stack.push('}');
else if (c == '[')
stack.push(']');
else if (stack.isEmpty() || stack.pop() != c)
// 닫는 괄호가 나올 경우, 스택에 마지막으로 담았던 닫는 괄호와 동일하지 않는다면
// 유효한 문자열이 아니다.
return false;
}
// 스택이 비워져있다면 모든 괄호가 짝으로 매칭이 되어 유효한 문자열을 의미하고,
// 스택이 비워져있지 않다면 괄호 매칭이 안되어 남아있다는 것을 의미하기에 유효하지 않음
return stack.isEmpty();
}
}
- stack.pop()의 경우 if절에서 비교위해 사용되었지만 한 번 해당 함수를 호출하게 되면 일단 스택에서 값을 꺼낸다는 사실을 명심하자!
- 값을 비교하는 것과 스택에서 값을 꺼내어 제거하는 2가지 동작을 한 번에 수행한 참 똑똑하게 코드를 작성한 것 같다.
'Coding Test' 카테고리의 다른 글
[String] 02.대소문자 변환 (1) | 2023.12.29 |
---|---|
[String] 01.문자 찾기 (2) | 2023.12.29 |
[LeetCode - Easy] 14. Longest Common Prefix (0) | 2023.09.02 |
[LeetCode - Easy] 13. Roman to Integer (0) | 2023.09.01 |
[LeetCode - Easy] 9. Palindrome Number (0) | 2023.08.31 |