본문으로 바로가기

주어진 배열의 순열에서 다음에 나올 순열을 찾아서 리턴하는 문제입니다.

permutation of an array of integers is an arrangement of its members into a sequence or linear order.

  • For example, for arr = [1,2,3], the following are considered permutations of arr: [1,2,3], [1,3,2], [3,1,2], [2,3,1].

The next permutation of an array of integers is the next lexicographically greater permutation of its integer. More formally, if all the permutations of the array are sorted in one container according to their lexicographical order, then the next permutation of that array is the permutation that follows it in the sorted container. If such arrangement is not possible, the array must be rearranged as the lowest possible order (i.e., sorted in ascending order).

  • For example, the next permutation of arr = [1,2,3] is [1,3,2].
  • Similarly, the next permutation of arr = [2,3,1] is [3,1,2].
  • While the next permutation of arr = [3,2,1] is [1,2,3] because [3,2,1] does not have a lexicographical larger rearrangement.

Given an array of integers nums, find the next permutation of nums.

The replacement must be in place and use only constant extra memory.

Example 1:

Input: nums = [1,2,3]
Output: [1,3,2]

Example 2:

Input: nums = [3,2,1]
Output: [1,2,3]

Example 3:

Input: nums = [1,1,5]
Output: [1,5,1]

Constraints:

  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 100

Solution 1.

public void nextPermutation(int[] nums) {
    int len = nums.length;
    if(nums == null || len <= 1) return;
    int i = len - 2;
    while(i >= 0 && nums[i] >= nums[i + 1]) i--; // 1. Find first decreasing element
    if(i >= 0) {                                 // If not entirely descending
        int j = len - 1;                         // Start from the end
        while(nums[j] <= nums[i]) j--;           // 2. Find number just larger then [i]
        swap(nums, i, j);                        // 3. Swap i and j
    }
    reverse(nums, i + 1, len - 1);     // 4. Reverse the descending sequence
}

public void swap(int[] nums, int i, int j) {
    int tmp = nums[i];
    nums[i] = nums[j];
    nums[j] = tmp;
}

public void reverse(int[] nums, int i, int j) {
    while(i < j) swap(nums, i++, j--);
}

구현자체는 어렵지 않으나 공식을 알고 있어야 하기에 그리 좋은 문제 같지는 않습니다. 저도 문제를 풀어보기 전까지는 몰랐던 공식이라 실제로 코테에서 만났으면 모든 순열을 찾아서 풀었을 것 같네요 ㅜ 순열을 찾는 공식은 아래와 같습니다.

1. 먼저 끝에서부터 요소를 찾아 처음으로 오름차순을 깨는 요소의 위치를 찾습니다. (i)

2. i 이후 요소부터 [i]의 바로 다음숫자를 찾습니다.

3. i와 j를 swap합니다.

4. i 이후의 모든 요소를 reverse() 한뒤 값을 반환해주시면 됩니다.

Reference

 

Next Permutation - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com