코딩테스트
[프로그래머스] 자바(Java) - 올바른 괄호
수방방
2024. 7. 29. 22:43
🧩 문제
https://school.programmers.co.kr/learn/courses/30/lessons/12909
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
💡 알고리즘 설계 및 코드
- 일단 첫번째로 이 문제를 보고 스택을 사용해야겠다고 판단한 이유는
- 닫힌 괄호 `)` 가 열린 괄호 `(` 와 짝을 맞추는데, 단순히 아무 열린 괄호와 맞추는 것이 아니라 가장 가까운 열린 괄호와 짝이 맞춰져야 하기 때문입니다.
- 이러한 특징은 스택의 LIFO 구조와 비슷하고 즉, 최근에 삽입된 데이터를 대상으로 연산을 수행해야 하기 때문에 스택을 사용하는 것이 적합하다고 판단하였습니다.
- 열린 괄호를 만나면 스택에 추가합니다.
- 닫힌 괄호가 나온다면 스택에서 열린 괄호를 제거합니다. (짝기 맞춰졌기 때문에)
- 스택이 비어있는지 확인하여 모든 열린 괄호가 닫힌 괄호와 짝을 이루었는지 판단합니다.
import java.util.*;
class Solution {
boolean solution(String s) {
char[] ch = s.toCharArray();
Stack<Character> stack = new Stack<>();
for(char c : ch) {
if(c == '(') {
stack.push(c);
} else {
if(stack.isEmpty()) return false;
stack.pop();
}
}
return stack.isEmpty();
}
}
- 문자열을 문자 배열로 변환
- 입력 문자열 s를 `toCharArray()` 메서드를 사용하여 문자 배열 ch로 변환합니다.
- 스택 초기화
- 괄호의 짝을 맞추기 위해 빈 스택 `Stack`을 선언합니다.
- 문자 배열을 순회하면서 괄호 처리
- 현재 문자가 열린 괄호이면 스택에 `push()` 합니다.
- 현재 문자가 닫힌 괄호라면 스택이 비어있는지 확인합니다.
- 예를 들어, 문자열 `(()))` 에서 앞의 `(())` 는 짝이 맞아 상쇄되고, 맨 마지막 닫힌 괄호 `)` 를 만났을 때 스택이 비어 있으면, 올바른 짝이 없다는 의미이기 때문에 false 를 반환해줍니다.
- 그렇지 않으면 스택에서 최근 요소를 `pop()` 하여 짝을 맞춥니다.
- 스택이 비어 있으면 모든 괄호가 올바르게 짝을 맞춘 것이므로 `isEmpty()` 를 사용하여 true 를 반환하고, 그렇지 않으면 false 를 반환합니다.
⏱️ 시간 복잡도
이 문제에서 주어진 제안 사항에 따르면 문자열 s의 길이가 100,000 이하의 자연수로 제한됩니다.
N의 가용 범위가 100,000 이므로 최대 `O(NlogN)` 시간 복잡도까지 활용할 수 있습니다.
- 문자열 순회
- for 루프를 통해 문자열의 각 문자를 한 번씩 순회합니다.
- 문자열의 길이를 N이라 하면, 이 순회의 시간 복잡도는 O(N)입니다.
- 스택 연산
- 스택에 문자를 push 하거나 pop 하는 연산은 각각 O(1) 의 시간 복잡도를 가집니다.
- 각 호출은 상수 시간이므로 전체 루프 내에서의 스택 시간 복잡도는 O(N) * O(1) = O(N) 입니다.
- isEmpty()
- isEmpty() 의 시간 복잡도는 O(1) 입니다.
- 즉, 이 코드의 전체 시간 복잡도는 O(N) 입니다.