-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[01주차 김동주] 소트 #1
Conversation
2ba5fe8
to
99f2143
Compare
838d40a
to
3fe4ffd
Compare
def solve(N: int, A: list[int]): | ||
counter = [0] * (MAX_NUM+1) | ||
for a in A: | ||
counter[a] += 1 | ||
build(N, counter) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
문제에서 숫자의 배열이 주어지는데 숫자는 최대 50개고, 각 숫자는 1,000보다 작거나 같은 자연수 또는 0입니다.
이것을 연속된 두 수가 연속된 값이 아니게만 정렬하면 되는데,
우선 각 숫자의 등장 횟수를 세어봅시다.
def build(N: int, counter: list[int], stack: list[int] = []): | ||
if len(stack) == N: | ||
print(' '.join(map(str, stack))) | ||
exit() | ||
for n in generate_possible_numbers(counter, stack): | ||
stack.append(n) | ||
counter[n] -= 1 | ||
build(N, counter, stack) | ||
counter[n] += 1 | ||
stack.pop() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이어서 각 숫자 별 등장 횟수를 센 counter 배열과, 스택만으로 문제에서 요구하는 수열을 만들 수가 있습니다.
스택에는 만들어진/완성된 수열이 담기게 됩니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 아직 스택 활용하는 부분이 익숙치 않은데 이런식으로 적용하면 비슷한 다른 문제도 다양하게 적용시킬 수 있겠군요 참고하겠습니다 ㅎㅎ
if len(stack) == N: | ||
print(' '.join(map(str, stack))) | ||
exit() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
모든 숫자를 다 채웠으면 완성된 수열을 출력하고 프로그램을 종료합니다.
stack.append(n) | ||
counter[n] -= 1 | ||
build(N, counter, stack) | ||
counter[n] += 1 | ||
stack.pop() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
여기서는 가능한 수열 조합을 그리디하게 만들어가다가, 더 이상 문제의 조건을 만족하는 수열을 만들 수 없을 때 다시 stack의 top으로 되돌아가며 다른 조합을 찾아보게 됩니다.
뒤로 돌아가서 다시 추적을 한다는 의미에서 백트레킹이라고 부를 수 있지 않을까 싶네요
stack.pop() | ||
|
||
|
||
def generate_possible_numbers(counter: list[int], stack: list[int]): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저.. 좀 초짜같은 놀라움이긴 한데요, 파이썬에서 이렇게 타입 지정할 때 리스트 안에 들어갈 타입까지도 지정이 가능한 걸 지금 알았네요.
요즘 파이썬으로 프로그램 작성하면 최대한 타입 지정해서 사용하려고 하는데, 참고해보겠습니당..
def generate_possible_numbers(counter: list[int], stack: list[int]): | ||
for i in range(MAX_NUM+1): | ||
if counter[i] > 0 and (not stack or i != stack[-1]+1): | ||
yield i |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yield 라는 키워드를 처음봐서 검색해보고 왔는데 성능 측면에서 이점을 보기위해서 사용한다고 하는데 그점을 노리고 사용하신건지 아님 또 다른 이유가 있는지 궁금합니다
def build(N: int, counter: list[int], stack: list[int] = []): | ||
if len(stack) == N: | ||
print(' '.join(map(str, stack))) | ||
exit() | ||
for n in generate_possible_numbers(counter, stack): | ||
stack.append(n) | ||
counter[n] -= 1 | ||
build(N, counter, stack) | ||
counter[n] += 1 | ||
stack.pop() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 아직 스택 활용하는 부분이 익숙치 않은데 이런식으로 적용하면 비슷한 다른 문제도 다양하게 적용시킬 수 있겠군요 참고하겠습니다 ㅎㅎ
🖊️ 풀이
스택과 카운터에 기반한 탐욕 알고리즘으로 풀이하였습니다.
플레티넘 문제 치고는 상당히 쉬운 난이도였던 것 같습니다. 여러분도 도전해보세요!