괄호가 바르게 짝지어졌다는 것은 '(' 문자로 열렸으면 반드시 짝지어서 ')' 문자로 닫혀야 한다는 뜻입니다. 예를 들어
- "()()" 또는 "(())()" 는 올바른 괄호입니다.
- ")()(" 또는 "(()(" 는 올바르지 않은 괄호입니다.
'(' 또는 ')' 로만 이루어진 문자열 s가 주어졌을 때, 문자열 s가 올바른 괄호이면 true를 return 하고, 올바르지 않은 괄호이면 false를 return 하는 solution 함수를 완성해 주세요.
- 문자열 s의 길이 : 100,000 이하의 자연수
- 문자열 s는 '(' 또는 ')' 로만 이루어져 있습니다.
입출력 예 #1,2,3,4
문제의 예시와 같습니다.
function solution(s) {
let answer = true;
s = s.split("");
let open = s.filter((v) => v === "(").length;
let close = s.filter((v) => v === ")").length;
answer = open === close ? (s[0] === "(" ? true : false) : false;
return answer;
}
만약 같은 테스트케이스가 실패했다면 아래의 반례를 넣어보자.
s: "()))((()"
단순히 열린 괄호와 닫힌 괄호의 개수를 센 다음, 첫 괄호가 열린 괄호, 마지막 괄호가 닫힌 것을 판별하는 방법으로 문제를 해결한다면 해당 반례에서는 실패할 확률이 높다. 열렸으면 닫아주는 과정이 무조건 필요한데 가장 처음의 괄호와 가장 마지막의 괄호를 제외한 내부에서는 열린괄호보다 닫힌괄호가 먼저 나오더라도 조건에 걸리지 않는다.
따라서 열렸을 때 1을 더해주고 닫혔을 때 1을 빼주고 하는 방법으로 해결하였다.
function solution(s) {
let answer = true;
let sum = 0;
s = s.split("");
for (let i = 0; i < s.length; i++) {
s[i] === "(" ? sum++ : sum--;
if (sum < 0) {
answer = false;
return answer;
}
}
answer = sum === 0 ? true : false;
return answer;
}
반복문을 통해 문자열을 돌면서 sum 변수에 열렸을 시에는 1을 더해주고 닫혔을 시에는 1을 빼준다. 만약에 열린 괄호보다 닫힌 괄호가 많을 시에는 sum 변수는 음수가 되고 문제 조건에 부합하지 않기 때문에 해당 조건일 때 false를 바로 return 해준다. 반복문이 끝난 이후에 만약 sum이 0이 아닌 양수이면 닫힌 괄호보다 열린 괄호가 많다는 뜻이므로 false를 return 해주고, 0일 시에만 쌍이 잘 맞는다는 뜻이니 true를 return 해준다.
해당 문제는 스택/큐 카테고리에 해당하는 문제이기 때문에 sum 변수를 선언하지 않고 stack을 통한 pop을 통해 해결할 수도 있다..!