1 <= nums.length <= 100
0 <= nums[i] <= 100
다음 조합을 찾는 방법의 포인트는 2가지 이다.
54321
의 다음은 12345
→ 뒤에서부터 숫자를 볼때, 모두 오름차순이면 처음부터 끝까지 범위의 수를 reverse12354
의 다음은 12435
→ 뒤에서부터 숫자를 볼때, 처음으로 오름차순이 아닌 수(3
)의 idx = 2
(오름차순이었다는 말은 해당 구간은 최대값이므로 오름차순이 아닌 수를 다음 수로 바꿔야함)
(ex. 132
다음 수는 213
)
→ 2~끝의 숫자를 뒤에서부터 볼때, 처음으로 3
보다 큰 수 4
(처음으로 3
보다 큰 수를 찾았지만, 결국 이 수는 3
보다 1 큰 값)
→ 두 수를 스왑 ⇒ 12453
(앞자리 변경 354
→ 453
)
→ idx 2 이후의 수들 reverse ⇒ 12435
(앞자리 변경 후, 나머지 수는 최소의 값을 가져야 하므로)규칙..?
class Solution {
var nums = intArrayOf()
fun nextPermutation(nums_: IntArray): Unit {
nums = nums_
var i = nums.size - 2
// 배열의 끝에서부터 처음으로 이동하며 오름차순이 아닌 idx(i) 찾기
while (i >= 0 && nums[i + 1] <= nums[i]) {
i--
}
if (i >= 0) {
var j = nums.size - 1
// i 이후의 원소중 뒤에서 처음으로 i 보다 큰 값을 가진 idx(j) 찾기
while (nums[j] <= nums[i]) {
j--
}
// i, j 스왑
nums[i] = nums[j].also { nums[j] = nums[i] }
}
// i 이후 원소들 reverse
reverse(i + 1)
}
// idx = start 이후 원소들 역순으로 뒤집기
fun reverse(start: Int) {
var i = start
var j = nums.size - 1;
while (i < j) {
nums[i] = nums[j].also { nums[j] = nums[i] }
i++
j--
}
}
}
시간 복잡도: 배열 순회 = n