n개의 괄호쌍 만들기
n개의 괄호쌍 만들기 — #LeetCode #개발자의도구들 only 파이썬 목표 참고 : 여기 전략 선택하기 DFS로 풀어보기 틀렸다 이전...
#LeetCode#Naver Blog
#LeetCode #개발자의도구들
- only 파이썬
- 목표 참고 : 여기
전략 선택하기
LeetCode(medium 22.Generate Parentheses 76.5%
🤔 순열과 조합이다
>>> 이런건 보통 backtracking으로 풀었던 것 같은데...
>>> ✅ DFS로 가능한 모든 경우의수를 선택할 수 있다.
DFS로 풀어보기
✅ )는 무조건 (이 있어야 선택 될 수 있다.
✅ ( 뒤에는 )혹은 (를 선택해야 한다.
✅ n값이 주어지면 가장 처음 (를 넣는다.
✅ n값에 맞춰 ( 혹은 )를 결정해야한다.
>>> n = 1이라면 초기값에 의해 다음은 )밖에 없다.
>>> n = 2이라면 초기값에 의해 (이 이미 선택되었으니, ( 혹은 )를 넣어야 한다.
✅ 전에 )이 선택되었다면 괄호가 완성된 것이니 다음값은 무조건 (이다.
>>> if before == ')' then must choice "("
✅ 각 단계에서 가능한 모든 경우의 수로 뻗어 나가자
>>> 배운 backtracking 활용
🗝️ 종료조건
>>> 만들어진 string이 n크기 여야 한다.
class Solution(object):
def generateParenthesis(self, n):
"""
:type n: int
:rtype: List[str]
"""
result = []
def dfs(parent, left):
if len(parent) == n * 2:
print("parent, ", parent)
result.append(parent)
return
if parent[-1] == "(":
if left < n:
left += 1
dfs(parent + "(", left + 1)
dfs(parent + ")", left)
else:
dfs(parent + ")", left)
elif parent[-1] == ")":
dfs(parent + "(", left + 1)
dfs("(", 1)
return result
- 틀렸다
- 이전값 ")" 뒤에 "("이 무조건 와야하는 것이 아니다.
- "(())"이 될 수 있다.
- 고로 이전값을 보고 추가하는 것은 틀린 방법이다.
- right을 무시하면 안된다.
- ()))))) 처럼 ")"가 무한히 연속적으로 붙을 수 있다.
- right 도 체크해줘야 한다.
로직 변경하여 도전하기
✏️ 논리 수정하기
✅ left처럼 right에도 제한을 둬야한다.
>>> left < right가 되는 경우의 수를 모두 제거해야한다.
ex) n = 2 -> ()) 와 같은 경우 \
🗝️ 항상 right는 left보다 작거나 같아야 함을 알 수 있다.
✅ 이전 값을 볼 필요는 없다. 그냥 left, right 만 보면 된다.
class Solution(object):
def generateParenthesis(self, n):
"""
:type n: int
:rtype: List[str]
"""
result = []
def dfs(parent, left, right):
if len(parent) == n * 2:
result.append(parent)
return
if left < right:
return
if left == n:
dfs(parent + ")", left, right + 1)
else:
dfs(parent + "(", left + 1, right)
dfs(parent + ")", left, right + 1)
dfs("(", 1, 0)
return result
# n = 3
# (
# (((
# ()
- 정답이다
- 28.88Beats를 기록했다.
- 시간 복잡도는 O(2ⁿ)이다.
- n 길이에 따라 경우의 수가 계속 증가하기 때문.
- right가 무한확장 되는 것을 막도록 구현
- 이전글 backtring처럼 string마다 확장되도록 구현
- 길이가 원하는 만큼 확장되면 reutnr 되도록 - 종료시점 명시
유형 정리
- DFS는 현재 상황에사 가능한 모든 경우의 수를 생각하여 뻡어나가는 전략이다.
- recursive로 구현할 때는 종료조건을 꼭 정확히 명시하도록 하자.