
난이도 : Level 2
문제 출처
문자열 s가 주어졌을 때, 괄호가 올바르게 열리고 닫혀 있는지 판단하는 문제이다.
예를 들어 "()", "(())" 같은 경우는 올바른 괄호이므로 true를 반환하고, ")(", "(()" 같은 경우는 올바르지 않으므로 false를 반환해야 한다.
처음에는 다음과 같이 생각했다.
)라면 올바른 괄호가 아니다.(라면 올바른 괄호가 아니다.(는 +1, 닫는 괄호 )는 -1로 처리한다.false를 반환한다.0이면 괄호의 짝이 맞으므로 true를 반환한다.핵심은 괄호의 개수를 직접 세는 것이다.
(를 만나면 아직 닫히지 않은 괄호가 하나 생긴 것이므로 count += 1을 해주고,
)를 만나면 열린 괄호 하나를 닫는 것이므로 count -= 1을 해준다.
이때 count가 중간에 음수가 된다면, 여는 괄호보다 닫는 괄호가 먼저 많이 나온 상황이다.
예를 들어 다음과 같은 경우이다.
())(
이 경우는 전체 개수만 보면 여는 괄호 2개, 닫는 괄호 2개라서 개수는 같지만, 중간에 닫는 괄호가 먼저 초과되기 때문에 올바른 괄호가 아니다.
따라서 단순히 최종 개수만 보는 것이 아니라, 순회 중간에 count < 0이 되는지도 확인해야 한다.
function solution(s) {
let count = 0;
if (s[0] === ")") {
return false;
} else if (s[s.length - 1] === "(") {
return false;
} else {
for (const ch of s) {
if (ch === "(") {
count += 1;
} else {
count -= 1;
if (count < 0) {
return false;
}
}
}
}
return count === 0 ? true : false;
}
def solution(s):
count = 0
if s[0] == ")":
return False
elif s[-1] == "(":
return False
else:
for ch in s:
if ch == "(":
count += 1
else:
count -= 1
if count < 0:
return False
return count == 0
처음에는 문자열의 첫 번째 문자와 마지막 문자를 따로 검사했다.
다만 JavaScript에서는 Python처럼 s[-1]로 마지막 문자를 가져올 수 없다.
마지막 문자를 가져오려면 s[s.length - 1]을 사용해야 한다.
또한 count = 0처럼 선언 없이 쓰는 것보다, let count = 0처럼 명확하게 변수를 선언하는 것이 좋다.
function solution(s) {
let count = 0;
for (const ch of s) {
if (ch === "(") {
count += 1;
} else {
count -= 1;
}
if (count < 0) {
return false;
}
}
return count === 0;
}
사실 처음과 끝을 따로 확인할 필요는 없었다.
문자열이 )로 시작한다면 첫 순회에서 바로 count가 -1이 되기 때문에 false가 반환된다.
문자열이 (로 끝난다면 모든 순회가 끝났을 때 count가 0이 아니므로 false가 반환된다.
즉, 아래 두 조건만으로 충분하다.
count < 0이 되면 falsecount === 0이면 true핵심 로직은 다음과 같다.
(를 만나면 count + 1)를 만나면 count - 1count가 음수가 되면 올바르지 않음count가 0이면 올바른 괄호function solution(s){
// score이 음수가 되면 false 얼리 리턴
score = 0
for (const char of s) {
if (char == "("){
score += 1
}
else { // s 는 문제에서 무조건 "(" or ")" 이라 제시됨
score -= 1
if (score < 0) {
return false
}
}
}
// 다 돌고나서 score가 0이 되어야 함
return score == 0
}