Profile image with cat

Jaehee

Hi!

Thumbnail of LeetCode - 20. Valid Parentheses

LeetCode - 20. Valid Parentheses LeetCode

작성일 : 2021년 12월 03일  / 수정일 : 2024년 06월 06일

목차

  1. 문제 개요
  2. 풀이
    1. Solution - Stack
      1. 제출 결과

문제 개요

난이도 - EASY 사용 언어 - C++

문자열이 주어질 때 소괄호(), 중괄호{}, 대괄호[]가 올바른 순서로 잘 열리고 닫혔는지 확인하는 문제입니다.

문제 - LeetCode - 20. Valid Parentheses

풀이

My Solutions(Github)

Solution - Stack

괄호는 늘 짝을 지어 닫혀야합니다. 또한 소괄호내에 또 소괄호가 열리거나, 다른 괄호내에 다른 괄호가 열리는 등 괄호가 중첩되기때문에 새로운 괄호가 열리면 해당 괄호에 짝인 닫힘 괄호가 등장하여야 합니다.

때문에 문자열을 순회하면서 가장 최근에 열린 괄호의 짝을 찾아야 하며, 해당 괄호의 짝을 찾고 나면 이전에 순회되었던 열린 괄호의 짝을 찾아야 합니다.

즉 FILO(First In Last Out)로 맨 처음에 순회되었던 괄호가 가장 나중에 닫혀야 합니다. 그러므로 이번 문제 풀이를 위해 스택 자료구조를 사용합니다.

stack<char> openBrackets;

C++ STL의 stack 자료구조를 선언합니다.

for (char ch : s)
{
    ...
}

그리고 입력된 문자열을 순회합니다. 반복문 내에서 괄호가 올바르게 열렸고, 닫혔는지 확인합니다.

if ('(' == ch || '{' == ch || '[' == ch)
{
    openBrackets.push(ch);
}

처음으로는 열린 괄호를 확인합니다. 열린 괄호라면 스택에 삽입해 가장 최근에 삽입된(스택의 top) 열린 괄호의 짝인 닫힌 괄호를 찾습니다.

else if (')' == ch || '}' == ch || ']' == ch)
{
    if (openBrackets.size() == 0) return false;
 
    char openBracket = openBrackets.top();
 
    if (
        !(
            ('(' == openBracket && ')' == ch) || 
            ('{' == openBracket && '}' == ch) || 
            ('[' == openBracket && ']' == ch)
        )
    )
    {
        return false;
    }
 
    openBrackets.pop();
}

만약 닫힌 괄호라면 스택의 top을 가져와 가장 최근에 탐색된 열린 괄호와 짝인지 확인합니다. 만약 아니라면 함수는 false를 반환하며, 짝이라면 스택에서 해당 열린 괄호를 pop하고 계속 순회를 합니다.

닫힌 괄호가 등장했는데, 열린 괄호를 저장하는 스택의 크기가 0이라면 잘 못 닫힌 괄호이므로 즉시 함수는 false를 반환합니다.

return openBrackets.size() == 0;

모든 순회가 끝나고 나면 함수를 반환합니다. 단, 만약 스택의 크기가 0이 아니라면 정상적으로 닫히지 않은 괄호가 있는 뜻이니, false를 반환하도록 합니다.

추가적으로 자잘한 최적화를 위해서 함수의 시작 부분에 다음 구문을 추가하였습니다.

if (s.size() % 2 != 0) return false;

정상적으로 열리고 닫힌 괄호는 2개의 문자로 이루어졌으므로, 만약 입력된 문자열의 길이가 홀수라면 하나의 문자는 정상적으로 닫히거나 열리지 않았다는 의미가 됩니다.

그러므로 입력된 문자열의 길이가 홀수라면 즉시 false를 반환합니다.

제출 결과

Solution 1 result

코드 전문
class Solution 
{
public:
    bool isValid(string s) 
    {
        if (s.size() % 2 != 0) return false;
 
        stack<char> openBrackets;
 
        for (char ch : s)
        {
            if ('(' == ch || '{' == ch || '[' == ch)
            {
                openBrackets.push(ch);
            }
            else if (')' == ch || '}' == ch || ']' == ch)
            {
                if (openBrackets.size() == 0) return false;
 
                char openBracket = openBrackets.top();
 
                if (
                    !(
                        ('(' == openBracket && ')' == ch) || 
                        ('{' == openBracket && '}' == ch) || 
                        ('[' == openBracket && ']' == ch)
                    )
                )
                {
                    return false;
                }
 
                openBrackets.pop();
            }
        }
 
        return openBrackets.size() == 0;
    }
};

LeetCode  시리즈의 다른 게시물 보기

Thumbnail of LeetCode - 24. Swap Nodes in Pairs

주어진 연결 리스트의 근접 노드와 짝을 지어 swap 합니다.

2021년 12월 09일

Thumbnail of LeetCode - 23. Merge k Sorted Lists

정렬된 K개의 연결 리스트를 모두 하나의 연결 리스트로 합쳐야합니다.

2021년 12월 08일

Thumbnail of LeetCode - 22. Generate Parentheses

정수 N이 주어질 때 N개의 소괄호로 이뤄지는 모든 조합을 생성합니다.

2021년 12월 07일

Thumbnail of LeetCode - 21. Merge Two Sorted Lists

정렬되어있는 두 연결 리스트를 하나로 합쳐야합니다.

2021년 12월 06일

Thumbnail of LeetCode - 20. Valid Parentheses

주어진 문자열에서 열린 괄호과 닫힌 괄호가 올바르게 존재하는지 확인합니다.

2021년 12월 03일

Thumbnail of LeetCode - 19. Remove Nth Node From End of List

단방향 연결 리스트의 끝에서 N번째 노드를 제거합니다.

2021년 12월 01일

Thumbnail of LeetCode - 18. 4Sum

정수 배열 내 숫자 네 개를 더해 target 숫자를 구할 수 있는 모든 가짓수를 찾습니다.

2021년 11월 29일

Thumbnail of LeetCode - 17. Letter Combinations of a Phone Number

2에서 9사이의 숫자로 구성된 문자열 입력 시 핸드폰 키보드에 매핑되는 문자열 조합을 생성합니다.

2021년 11월 26일