[C++] 백준(BOJ) - 15926 : 현욱은 괄호왕이야!!

인프런에 있는 큰돌님의 강의 10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트를 듣고 정리한 필기입니다.

문제

BOJ - 15926 : 현욱은 괄호왕이야!!(링크)

여는 괄호 ‘(’와 닫는 괄호 ‘)’로 구성된 문자열에서 아래의 조건을 만족하는 문자열을 올바른 괄호 문자열이라고 부른다.

  1. () 는 올바른 괄호 문자열이다
  2. 어떤 문자열 x가 올바른 괄호 문자열이라면, (x)도 올바른 괄호 문자열이다.
  3. 어떤 문자열 x와 y가 올바른 괄호 문자열이라면, xy도 올바른 괄호 문자열이다.
    현욱은 친구로부터 생일 선물로 굉장히 긴 괄호 문자열을 받았다(도대체 왜 이런 걸 선물하는걸까?). 하지만 현욱은 올바른 괄호 문자열이 아니면 굉장히 싫어하기 때문에, 받은 괄호 문자열에서 연속한 일부분을 잘라서 올바른 괄호 문자열을 만들려고 한다. 그리고 이왕이면 긴 문자열이 좋으니 현욱은 부분 구간을 최대한 길게 잘라내려고 한다. 현욱을 도와 주어진 괄호 문자열에서 위의 조건을 만족하는 가장 긴 부분 문자열의 길이를 계산하는 프로그램을 작성해보자.

입력

첫 줄에 문자열의 길이 n (1 ≤ n ≤ 200,000)이 주어진다.

둘째 줄에 괄호로만 구성된 길이 n짜리 문자열이 주어진다.

출력

주어진 문자열에서 길이가 가장 길면서 올바른 괄호 문자열인 부분 문자열의 길이를 출력한다. 올바른 괄호 문자열인 부분 문자열을 찾을 수 없는 경우 0을 출력한다.

알고리즘

  1. 문자열
  2. 스택
  3. 배열

풀이

  1. 배열을 활용
    - 올바른 괄호 영역은 1로 아닌 부분은 0으로 채워진 일차원 배열을 만들어서 일차원 배열이 가장 길게 1로 이루어진 부분을 리턴

  2. 스택만을 사용 - 스택에 분기점 (-1) 을 시작 부분에 삽입해 준 후 올바른 괄호가 나올 때마다 인덱스의 차를 구해가며 최대값을 구하고, ‘(‘ 가 스택에서 모두 없어졌을 때는 분기점을 초기화해가며 최대값을 계속해서 다시 구하는 알고리즘을 구성

코드 1 - 배열

// BOJ-15926 : 현욱은 괄호왕이야!!
#include<bits/stdc++.h>
using namespace std;

int n, res, cnt, d[200001];
string s;
stack<int> stk;

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	cin >> n >> s;

	for (int i = 0; i < n; i++)
	{
		if (s[i] == '(') stk.push(i);
		else if (stk.size())
		{
			d[i] = d[stk.top()] = 1;
			stk.pop();
		}
	}

	for (int i = 0; i < n; i++)
	{
		if (d[i])
		{
			cnt++;
			res = max(res, cnt);
		}
		else cnt = 0;
	}

	cout << res << '\n';

	return 0;
}

코드 2 - 배열

// BOJ-15926 : 현욱은 괄호왕이야!!
#include<bits/stdc++.h>
using namespace std;

int n, res;
string s;
stack<int> stk;

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	cin >> n >> s;

	stk.push(-1);
	for (int i = 0; i < n; i++)
	{
		if (s[i] == '(') stk.push(i);
		if (s[i] == ')')
		{
			stk.pop();
			if (!stk.empty())
			{
				res = max(res, i - stk.top());
			}
			else stk.push(i);
		}
	}
	cout << res << '\n';

	return 0;
}

평가

  • 일차원 배열을 활용하여 문제 풀이를 하는 방법이 비교적 간단하지만 스택만을 이용해 다양한 방식으로 문제 풀이를 할 수 있다는 것을 학습

© 2023 Jinsoo Lee. All rights reserved.

Powered by Hydejack v9.1.6