ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 15926 현욱은 괄호왕이야!!
    백준/스택 2022. 5. 5. 21:15

    다른 사람 블로그를 참고했다.

     

    1. 풀이

     

    <예시1>

    5
    (())(

     

    일단 input 배열에 입력값을 받는다.

    스택(stack)을 이용한다.

    제일 먼저 stack에 -1을 넣는다.

    이유는 나중에 알게 된다. 

     

    규칙

    1. input[i] 값 = ( 

    => stack에 i 값을 넣는다.

     

    2. input[i] 값 = )

    => stack에서 값 하나를 꺼낸다.

      2-1. 이후에 만약 stack이 비어있으면, stack에 i 값을 넣는다.

      2-2. stack이 비어있지 않으면, i-stack.peek() 로 올바른 괄호 문자열 길이를 구한 뒤,

           올바른 괄호 문자열의 최대 길이를 다시 정해준다.

     

    예시1을 가지고 자세히 살펴보자.

    for 문을 이용한다.

     

    1) i = 0 일때

     

    문자열의 맨 처음은 (이다.

    이때는 i 값을 stack에 집어넣는다.

    그런데 맨 처음에 stack에는 -1 이 들어간다고 했다.

    => stack : -1,0

     

    2) i =1

    두 번째 문자는 ( 이다.

    => stack 에 1 집어 넣음

    => stack : -1,0,1

     

    3) i =2

    세 번째 값은 ) 이다.

    => stack 에서 값을 하나 꺼낸다.

    => stack : -1,0

     

    이후에 올바른 괄호 문자열 길이를 구한다.

    i =1 에서 문자는 ( 였다.

    i =2 일때 ) 이므로

    ( ) 가 올바른 괄호 문자열로 완성된다. 그리고 이 길이는 2이다.

     

    위에서 올바른 괄호 문자열 길이를 i-stack.peek() 로 구한다고 했다.

    i = 2 이고, stack.peek() = 0 이다.

    즉 길이가 2가 된다.

    위에서 구한 길이와 같음을 알 수 있다.

     

    4) i =3 

    네 번째 값은 ) 이다.

    => stack 에서 값을 하나 꺼낸다.

    => stack: -1

     

    => 길이 : i -stack.peek() = 3 - (-1) = 4

    첫번째부터 네번째까지 문자열을 살펴보면

    ( ( ) ) 이다.

    올바른 괄호 문자열 길이가 4이다.

    즉 위에서 구한 길이와 같음을 알 수 있다.

     

     

    5) i = 4

    다섯 번째 문자는 ( 이다.

    => stack에 4 집어 넣음

    => stack : -1, 4

     

     

    올바른 괄호 문자열의 길이 중 최댓값은 4이며, 정답이 된다.

     

     

    <예시2>

    6

    (()()(

     

    맨 처음 stack 에는 -1 이 들어간다.

     

    1) i =0 일때

    문자는 ( 이다.

    => stack 에 0 집어넣음

    => stack : -1,0

     

    2) i = 1 일때

    문자는 ( 이다.

    => stack : -1,0,1

     

    3) i = 2

    문자는 ) 이다.

    => stack에서 값을 하나 꺼낸다.

    => stack : -1,0

     

    올바른 괄호 문자열 길이 : i - stack.peek() = 2-0 = 2

    올바른 괄호 문자열의 최대 길이 : 2

     

    4) i = 3

    문자는 ( 이다.

    => stack에 3을 넣는다.

    => stack : -1,0,3

     

    5) i = 4

    문자는 ) 이다.

    => stack에서 값을 하나 꺼낸다.

    => stack : -1,0

     

    올바른 괄호 문자열 길이 : i - stack.peek() = 4 - 0 = 4

    즉 입력값인 (()()( 에서

    ()() 부분이 올바른 괄호 문자열인데, 길이가 4이다.

     

     

    6) i = 5

    문자는 ( 이다.

    => stack 에 5를 집어 넣는다.

    => stack : -1,0,5

     

    <예시 3>

    5

    ())()

     

    위에서 맨 처음 stack에 -1 을 넣는다고 했다. 그 이유를 여기서 알 수 있다.

     

    1) i = 0

    첫 번째 문자는 ( 이다.

    => stack에 0을 넣는다.

    => stack : -1,0

     

    2) i = 1

    문자는 ) 이다.

    => stack에서 값을 하나 꺼낸다.

    => stack : -1

     

    길이 : i - stack.peek() = 1 - (-1) = 2

     

    여기서 stack의 맨 처음 값 -1 이 쓰였다.

    즉, ) 문자가 나왔을 때,

    만약 앞에 ( 문자가 있었다면 올바른 괄호 문자열을 만들 수 있는데, 그 길이는  

    ( 의 인덱스가 아니라 ( 의 인덱스보다 먼저 stack에 들어가 있는 값으로 구해진다.

     

    즉, 여기서 ( 의 인덱스는 0 이지만, 

    길이를 구할 때 보면, -1, 즉 ( 의 인덱스 0 보다 먼저 stack에 들어간 -1 이 사용됨을 알 수 있다.

    때문에 길이를 구하기 위해 -1 을 제일 앞에 넣은 것이다.

     

    3) i = 2

    문자는 ) 이다.

    => stack 에서 값을 꺼낸다.

    => stack 이 비어있다.

    이 경우는 길이를 구하는 게 아니고, 그냥 i = 2 를 stack에 넣어주면 된다.

    => stack : 2

     

     

    4) i = 3

    문자는 ( 이다.

    => stack에 i = 3 을 넣는다.

    => stack : 2, 3

     

    5) i = 4

    문자는 ) 이다.

    => stack에서 값을 꺼낸다.

    => stack : 2

     

    길이 : i - stack.peek() = 4 - 2 = 2

     

    올바른 괄호 문자열 길이 중 최댓값은 2로 정답이다.

     

    2. 최종 코드

     

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.Stack;
    
    public class Main {
    
    	public static void main(String[] args) throws IOException {
    				
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		int n = Integer.parseInt(br.readLine());
    		String input [] = br.readLine().split("");
    		
    		Stack<Integer> stack = new Stack<>();
    	
    		int max = 0;
    		stack.push(-1);
    	
    		for(int i=0; i<n;i++) {
    			
    			if(input[i].equals("(")) {
    				stack.push(i);
    				
    			}else {
    				stack.pop();
    			
    				if(stack.isEmpty()) {
    					stack.push(i);
    				
    				}else {
    						
    				int length = i-stack.peek();
    				max = Math.max(max, length);
    				
    			}
    		  }
    	   }
    		
    		System.out.println(max);
    		
    	}
    }

     

     

    참고 블로그 :

    https://lms0806.tistory.com/48?category=873021 

     

    [백준] 15926번 : 현욱은 괄호왕이야!!(JAVA)

    https://www.acmicpc.net/problem/15926 15926번: 현욱은 괄호왕이야!! 첫 번째 입출력에서, 맨 처음 위치부터 4개를 잘라낸 (())가 가장 긴 올바른 괄호 문자열이다. 두 번째 입출력에서, 6번째 위치부터 8개를.

    lms0806.tistory.com

     

    '백준 > 스택' 카테고리의 다른 글

    10828 스택  (0) 2021.10.27

    댓글

Designed by Tistory.