-
next_permutation, prev_permutationProgramming/leetcode 2022. 4. 20. 09:23728x90
next_permutation, prev_permutation
c++의 레퍼런스에는 들어있지만, python에는 구현되어있지 않아 이 기회에 정리해둘겸 적어본다.
python에는 itertools을 이용하여 순열 전체를 구하는 방법은 있다
기본 원리
예를 들어, [1,2,3,4]라는 것을 순열을 만든다 가정해보자
[1, 2, 3, 4] : 오름차순 시작
[1, 2, 4, 3]
[1, 3, 2, 4]
[1, 3, 4, 2]
[1, 4, 3, 2]
[2, 1, 3, 4]
[2, 1, 4, 3]
[2, 3, 1, 4]
[2, 3, 4, 1]
[2, 4, 3, 1]
[3, 2, 4, 1]
[3, 4, 2, 1]
[4, 3, 2, 1] : 내림차순 마무리===> 오름차순으로 시작하고, 내림차순으로 끝이 난다.
그리고 중간에 [2,1,3,4]를 보면 특정 지점을 기준으로 오름차순, 내림차순이 이어진다.
1) 배열의 뒤에서부터 오름차순이 깨지는 부분을 찾자.
예를 들어, [1,3,4,2]가 있다고 하자
그 다음 순서를 찾기 위해서 맨 뒤에서부터 아래 조건으로 while문을 돌리자
#arr의 최대 길이 i = len(arr) - 1 #뒤에서부터 오름차순이 깨지는 곳을 찾자.. while (i>=0 and arr[i-1] >= arr[i]): i -= 1
2) [1,3,4,2]에서 오름차순이 깨지는 부분은 [3,4]이다.
3과 오름차순 부분[4,2]와 교체할 부분을 찾아야한다.
j = len(arr) - 1 # arr[i-1]보다 작으면서 [4,2]에서 arr[i-1]에 가장 가까운 값을 찾자.. while(arr[i-1] >= arr[j]): j-=1
왜 가장 가까운 값을 찾느냐하면 바꿨을 때 오름차순이 유지가 되어야하기 때문이다.
둘다 찾았으면 값을 바꿔주자
arr[i-1], arr[j] = arr[j], arr[i-1]
3) 이제 [1,2,4,3]이 완성되었다.
하지만 아직 한가지 처리가 더 필요하다. i 부터 j까지 배열을 뒤집어 줘야한다.
예를 들어 [2,3,4,1]에서 2)까지 진행을 했다면 [2,1,4,3] 이다.
여기서 [4,3]을 오름차순으로 만들어줘야지만 사전순 배치가 가능하다.
while(i<j): arr[i], arr[j] = arr[j], arr[i] i+=1 j-=1
전체 코드 (next_permutation)
arr = [1, 2, 3, 4] def next_permutation(): i = len(arr) - 1 # 뒤에서부터 오름차순을 찾는다...오름차순이 끝나는 지점 기록 while (i > 0 and arr[i-1] >= arr[i]): i -= 1 # 0미만으로 내려가면 더이상 없다.. if (i <= 0): return False j = len(arr) - 1 # i위치랑 교환할 j를 찾자.. while(arr[i-1] >= arr[j]): j -= 1 arr[i-1], arr[j] = arr[j], arr[i-1] # 이걸 왜 해야될까??????????????? # 사전순 배치때문에 필요한 부분이다. j = len(arr) -1 while (i < j): arr[i], arr[j] = arr[j], arr[i] i += 1 j -= 1 return True while True: print(arr) if (next_permutation()): continue break
전체 코드(prev_permutation)
arr = [9, 8, 7, 6] def prev_permutation(): i = len(arr) - 1 while (i > 0 and arr[i-1] < arr[i]): i -= 1 if (i <= 0): return False j = len(arr) - 1 while (arr[i-1] <= arr[j]): j -= 1 arr[i-1], arr[j] = arr[j], arr[i-1] j = len(arr) - 1 while (i < j): arr[i], arr[j] = arr[j], arr[i] i += 1 j -= 1 return True while True: print(arr) if (prev_permutation()): continue break
'Programming > leetcode' 카테고리의 다른 글
104. Maximum Depth of Binary Tree (1) 2021.03.17 743. Network Delay Time (0) 2021.03.10 78. Subsets (0) 2021.03.03 39. Combination Sum (0) 2021.03.03 17. Letter Combinations of a Phone Number (0) 2021.02.24