난이도: EASY
문제
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
Example 4:
Input: s = "([])"
Output: true
Constraints:
1 <= s.length <= 104
s consists of parentheses only '()[]{}'.
시도 1
class Solution {
public boolean isValid(String s) {
Stack<Char> st = new Stack<>();
for(int i = 0; i < s.length(); i++) {
// 여는 괄호면 push, 닫는 괄호면 pop 해서 매칭
if(s.charAt(i) == '(' || s.charAt(i) == '{' || s.charAt(i) == '[') {
st.push(s.charAt(i));
} else if(s.charAt(i) == ')') {
if(st.peek() == '(') st.pop();
} else if(s.charAt(i) == '}') {
if(st.peek() == '{') st.pop();
} else if(s.charAt(i) == ']') {
if(st.peek() == '[') st.pop();
}
}
if(st.isEmpty()) {
return true;
} else {
return false;
}
}
}
//----------------------------- 수정 코드 --------------------------------
class Solution {
public boolean isValid(String s) {
Stack<Character> st = new Stack<>();
for(int i = 0; i < s.length(); i++) {
// 여는 괄호면 push, 닫는 괄호면 pop 해서 매칭
if(s.charAt(i) == '(' || s.charAt(i) == '{' || s.charAt(i) == '[') {
st.push(s.charAt(i));
} else if(s.charAt(i) == ')') {
if(st.peek() == '(') st.pop();
} else if(s.charAt(i) == '}') {
if(st.peek() == '{') st.pop();
} else if(s.charAt(i) == ']') {
if(st.peek() == '[') st.pop();
}
}
if(st.isEmpty()) {
return true;
} else {
return false;
}
}
}
컴파일 오류. 뭐지..? 소문자인가.....했는데 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 제너릭에 기본형을 써서 난 거 였음. 제네릭에는 객체타입만 쓸 수 있다고...!!!! 기본적인것도 막 틀리네 너무오래쉬었다진짜 ㅠ 그리고 중간에 peek() 이거 기억안나서 메소드명 검색함 ㅋㅋㅋ....

제출했는데 저런 경우를 생각못해서 에러남. 처리 추가하기
시도2
class Solution {
public boolean isValid(String s) {
Stack<Character> st = new Stack<>();
for(int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
// 여는 괄호면 push, 닫는 괄호면 pop 해서 매칭
if(c == '(' || c == '{' || c == '[') {
st.push(c);
} else {
// 닫는 괄호가 나왔는데 스택이 비어있으면 false
if(st.isEmpty()) return false;
if(c == ')') {
if(st.peek() == '(') st.pop();
} else if(c == '}') {
if(st.peek() == '{') st.pop();
} else if(c == ']') {
if(st.peek() == '[') st.pop();
}
}
}
if(st.isEmpty()) {
return true;
} else {
return false;
}
}
}

ㅎㅎ 또실패 우리친구는 왜 안됐을까?
시도3
class Solution {
public boolean isValid(String s) {
Stack<Character> st = new Stack<>();
for(int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
// 여는 괄호면 push, 닫는 괄호면 pop 해서 매칭
if(c == '(' || c == '{' || c == '[') {
st.push(c);
} else {
// 닫는 괄호가 나왔는데 스택이 비어있으면 false
if(st.isEmpty()) return false;
char top = st.peek();
if(c == ')' && top == '(') st.pop();
else if(c == '}' && top == '{') st.pop();
else if(c == ']' && top == '[') st.pop();
else return false; // 짝이 안 맞으면 false
}
}
if(st.isEmpty()) {
return true;
} else {
return false;
}
}
}
나의 최종 제출 답안:
class Solution {
public boolean isValid(String s) {
Stack<Character> st = new Stack<>();
for(int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
// 여는 괄호면 push, 닫는 괄호면 pop 해서 매칭
if(c == '(' || c == '{' || c == '[') {
st.push(c);
} else {
// 닫는 괄호가 나왔는데 스택이 비어있으면 false
if(st.isEmpty()) return false;
char top = st.peek();
if(c == ')' && top == '('
|| c == '}' && top == '{'
|| c == ']' && top == '[') st.pop();
else return false; // 짝이 안 맞으면 false
}
}
return st.isEmpty();
}
}
줄일 수 있는 소스 정리해서 제출.

chatGPT에게 더 간단하고 효율적이게 수정해달라고 요청한 답안:
🔥 개선할 수 있는 부분
- st.peek()을 확인 후 st.pop() 하는 과정 단순화
- st.peek()을 따로 변수에 저장하고 비교한 후 st.pop()을 호출하는 대신, st.pop()을 직접 사용하면 더 깔끔함.
- 현재 코드:
char top = st.peek();
if(c == ')' && top == '('
|| c == '}' && top == '{'
|| c == ']' && top == '[') st.pop();
else return false;
개선 가능 코드:
if (!st.isEmpty() && (
(c == ')' && st.pop() == '(') ||
(c == '}' && st.pop() == '{') ||
(c == ']' && st.pop() == '[')
)) continue;
return false;
st.pop()을 실행한 후 반환값을 직접 비교하여 peek()을 따로 쓰지 않아도 됨.
- 맵을 활용한 괄호 매칭 (Map<Character, Character>)
- Map을 활용하면 조건문을 더 단순화할 수 있음.
- 매칭되는 괄호 쌍을 Map에 저장하여 if-else 대신 get()을 활용.
import java.util.*;
class Solution {
public boolean isValid(String s) {
Stack<Character> st = new Stack<>();
Map<Character, Character> pairs = Map.of(
')', '(',
'}', '{',
']', '['
);
for (char c : s.toCharArray()) {
if (pairs.containsKey(c)) { // 닫는 괄호일 경우
if (st.isEmpty() || st.pop() != pairs.get(c)) {
return false; // 스택이 비었거나 짝이 안 맞음
}
} else {
st.push(c); // 여는 괄호일 경우 push
}
}
return st.isEmpty(); // 모든 괄호가 맞으면 스택이 비어 있어야 함
}
}
🚀 개선된 코드의 장점
- Map을 활용하여 괄호 매칭을 더 효율적으로 수행
- 기존 코드에서는 if (c == ')' && top == '(' || ...) 처럼 여러 if-else 비교가 필요했지만, Map을 사용하면 pairs.get(c)을 통해 매칭 괄호를 바로 확인 가능.
- peek()을 사용하지 않고 pop()을 바로 수행하여 불필요한 연산 제거
- 기존 코드에서는 peek() 후 pop()을 했지만, 이제는 pop()을 직접 실행하여 비교.
- 코드 가독성이 향상됨
- Map을 사용하여 괄호 매칭을 관리하고, pairs.containsKey(c)를 통해 if-else 조건문을 줄여 더 직관적인 코드 작성 가능.
📌 성능 비교
코드if-else 조건문 개수추가 연산
| 기존 코드 | 3개 (if (c == ')' && top == '(' ...)) | peek(), pop() 사용 |
| 개선 코드 | 1개 (if (pairs.containsKey(c))) | pop() 바로 사용 |
📌 최적화된 코드가 더 짧고 가독성이 좋아 유지보수가 쉬우며, 실행 속도도 미세하게 개선됩니다! 🚀😊
'Coding Challenges > LeetCode' 카테고리의 다른 글
| [SQL50] 584. Find Customer Referee (5) | 2025.02.07 |
|---|---|
| [SQL50] 1757. Recyclable and Low Fat Products (1) | 2025.02.06 |
| [Java] 14. Longest Common Prefix (3) | 2025.02.05 |
| [Java] 13. Roman to Integer (2) | 2025.02.04 |
| [Java] 9. Palindrome Number (1) | 2025.02.03 |