1 minute read

Updated:

문제 설명

n개의 괄호 쌍으로 만들 수 있는 올바른 괄호의 갯수를 반환하는 함수를 완성하라.

올바른 괄호란 (())나 ()와 같이 올바르게 모두 닫힌 괄호를 의미한다.

문제 이해

  • 모든 케이스를 다 순회하면서 조건에 맞는 경우만 카운트하면 된다.
  • 괄호가 열렸다 닫히면서 여러 케이스가 생기고, 각 케이스에서 열리고 닫히는 순서를 달리하면서 또 다른 케이스가 파생되므로 선형으로 증가하지 않는다.
  • 비선형적으로 탐색하는 것 중 dfs(깊이우선탐색)을 사용한다.

그림으로 이해

  • (열리는 괄호, 닫히는 괄호)를 2차원 좌표로 표현하니 규칙을 찾는 게 수월했다.
  • 각각 괄호 갯수가 n과 같으면 올바른 괄호로 보고 갯수 count 값을 +1 해주면 된다. 그 전에, 올바르지 않은 괄호는 count되지 않도록 검사가 필요하다.
    • 시작은 열린 괄호부터
    • 열린 괄호가 n보다 클 수 없다.
    • 닫힌 괄호 갯수가 열린 괄호 갯수보다 클 수 없다.

슈도코드

class Solution {
    public int solution(int n) {
        int answer = 0;

        P(open, close) 저장하는 stack 만든다.
        stack 시작노드 P(1,0) 추가한다.(열린괄호로 먼저 시작해야한다.)
        while(스택이  때까지 반복한다.){
            가장 위에 있는 노드 P 꺼낸다.
            
            if(open n보다 크면){
                아래 코드 실행하지 않는다.
            }
            
            if(close보다 open 크면 ){
                아래 코드 실행하지 않는다.
            }
            
            if(open close 모두 사용되었으면){
                answer 1 증가시킨다.
            }
            
            stack 열린괄호(open +1) 추가한다.
            stack 닫힌괄호(close + 1) 추가한다.
        }
        return while 종료  answer 반환한다.
    }
}

구현 코드

import java.util.*;

class Solution {
    
    class P{
        int open; 
        int close;
        P(int open, int close){
            this.open = open;
            this.close = close;
        }
    }
    
    public int solution(int n) {
        int answer = 0;
        
        Stack<P> stack = new Stack<>();
        stack.push(new P(1,0));
        while(!stack.isEmpty()){
            P p = stack.pop();
            
            if(p.open > n) 
			    continue;
            if(p.open < p.close) 
				continue;
            if(p.open + p.close == 2*n) {
                answer++;
                continue;
            }
            stack.push(new P(p.open+1, p.close));
            stack.push(new P(p.open, p.close+1));
        }
        return answer;
    }
}