홈 LeetCode. 31. Next Permutation
글
취소

LeetCode. 31. Next Permutation

image

문제 링크

풀이

현재 순열보다 크면서 가능한 한 가장 작은 순열을 만들려면, 오른쪽에서부터 증가시킬 수 있는 가장 오른쪽 위치를 바꿔야 합니다. 오른쪽에서 왼쪽으로 탐색해 nums[i] < nums[i + 1]을 만족하는 첫 인덱스 i를 찾습니다. i 뒤의 접미부는 비증가 순서입니다. 그러한 인덱스가 없다면 배열 전체가 비증가 순서이므로 이미 가장 큰 순열이며, 배열을 뒤집어 가장 작은 순서로 만듭니다.

피벗이 있으면 접미부에서 nums[i]보다 큰 값 중 가장 오른쪽 값을 찾아 피벗과 교환합니다. 접미부가 비증가 순서이므로 이 가장 오른쪽의 큰 값이 피벗을 대체할 수 있는 가장 작은 값이며, 전체 순열을 더 크게 만드는 변화도 최소화합니다. 접미부를 뒤집으면 값이 오름차순이 되어 나머지 부분을 가능한 한 작게 만들 수 있습니다.

시간 복잡도는 O(N), 추가 공간 복잡도는 O(1)입니다.

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Solution {
    public void nextPermutation(int[] nums) {
        int pivot = nums.length - 2;
        while (pivot >= 0 && nums[pivot] >= nums[pivot + 1]) {
            pivot--;
        }

        if (pivot >= 0) {
            int successor = nums.length - 1;
            while (nums[successor] <= nums[pivot]) {
                successor--;
            }
            swap(nums, pivot, successor);
        }

        reverse(nums, pivot + 1, nums.length - 1);
    }

    private void reverse(int[] nums, int left, int right) {
        while (left < right) {
            swap(nums, left++, right--);
        }
    }

    private void swap(int[] nums, int left, int right) {
        int temp = nums[left];
        nums[left] = nums[right];
        nums[right] = temp;
    }
}
이 글은 저자가 CC BY 4.0 라이선스로 배포합니다.