문제 설명
문제
1부터 N까지의 수로 이루어진 순열이 있다. 이때, 사전순으로 다음에 오는 순열을 구하는 프로그램을 작성하시오.
사전 순으로 가장 앞서는 순열은 오름차순으로 이루어진 순열이고, 가장 마지막에 오는 순열은 내림차순으로 이루어진 순열이다.
N = 3인 경우에 사전순으로 순열을 나열하면 다음과 같다.
- 1, 2, 3
- 1, 3, 2
- 2, 1, 3
- 2, 3, 1
- 3, 1, 2
- 3, 2, 1
입력
- 첫째 줄에 N(1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄에 순열이 주어진다.
출력
- 첫째 줄에 입력으로 주어진 순열의 다음에 오는 순열을 출력한다. 만약, 사전순으로 마지막에 오는 순열인 경우에는 -1을 출력한다.
풀이 과정
- 어떻게 구현하는지 모르겠어서.. next_permutation 알고리즘을 찾아 봄
- 현재 순열을 오른쪽 -> 왼쪽으로 검사하면서 a[i] > a[i-1]인 i점을 찾음.
- 여기서, i-1번이 바꾸게 될 타겟임.
- 만약 맨 왼쪽까지 그런 점이 없다면 마지막 순열인 것
- 다시 현재 순열을 오른쪽 -> 왼쪽으로 검사하면서, 바꾸게 될 타겟보다 큰 값의 위치를 찾음.
- a[j] > a[i-1]인 점 j를 찾음.
- a[j]와 a[i-1]을 바꾸어 준다.
- 마지막으로, i번째 이후의 순열들을 오름차순으로 정렬해주면 된다. (i번째 순열 포함)
- 이 때, 사실상 i번째 이후의 순열들은 내림차순이므로 거꾸로 붙여주면 됨.
- 스왑으로 구현하여도 됨. (i <-> 맨 오른쪽), (i-1 <-> 맨 오른쪽-1), ...
소스 코드
import sys
n = int(sys.stdin.readline().rstrip())
sequence = list(map(int, sys.stdin.readline().rstrip().split()))
def next_permutation(sequence):
i = len(sequence) - 1
# sequence[i-1] < sequence[i]인 경우, sequence[i-1]이 바꾸게 될 타겟
while i > 0 and sequence[i-1] > sequence[i]:
i = i - 1
if i == 0:
return None
swap_pos = i-1
# 바꾸게 될 타겟보다 큰 값의 위치를 찾음
j = len(sequence) - 1
while j > 0 and sequence[swap_pos] >= sequence[j]:
j = j - 1
# 두 값을 서로 바꾸어 줌
sequence[swap_pos], sequence[j] = sequence[j], sequence[swap_pos]
k = len(sequence) - 1
sequence = sequence[:i] + (sequence[i:])[::-1]
return sequence
p = next_permutation(sequence)
if p == None:
print(-1)
else:
print(*p)
'알고리즘[Python] > 백준 알고리즘' 카테고리의 다른 글
[ 11057 ] [ DP ] 오르막 수 (0) | 2021.08.31 |
---|---|
[ 2230 ] [ Two-Pointer ] 수 고르기 (0) | 2021.08.31 |
[ 3986 ] [ Stack ] 좋은 단어 (0) | 2021.08.29 |
[ 9205 ] [ DFS ] 맥주 마시면서 걸어가기 (0) | 2021.08.29 |
[ 2573 ] [ BFS ] 빙산 (0) | 2021.08.28 |