↓Skip to main content
  1. LeetCode/

LeetCode 31: Next Permutation

·2 mins· ·
LeetCode Medium Array Two-Pointers
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: medium First Attempt: 2022-10-21

  • Submissions: Accepted → Runtime Error ×2 → Wrong Answer → Accepted ×2 → Wrong Answer → Accepted ×2 → Wrong Answer → Accepted ×2

Approach
#

The fixed steps of Next Permutation:

  1. From right to left find the first i with nums[i] < nums[i + 1]. The suffix i + 1.. is non-increasing, already the largest arrangement.
  2. If none exists (fully non-increasing), reverse everything into the smallest arrangement.
  3. From right to left find the first nums[j] > nums[i] and swap i and j.
  4. Reverse the part after i into increasing order.

With duplicates, steps 1 and 3 must skip equal values using >= / <=.

My Attempts
#

The 2022 versions used strict < / >, stopping at the wrong place with duplicates: [1, 3, 1] should become [3, 1, 1]; it became [1, 1, 3]; another moved j rightward while searching for the swap partner and ran out of range. In 2026 one version reversed from i + 1, but its i pointed one past the dip, so one element too few was reversed: [2, 3, 3] should become [3, 2, 3]; it became [3, 3, 2].

Solution
#

class Solution:
    def nextPermutation(self, nums: List[int]) -> None:
        n = len(nums)
        i = n - 2
        while i >= 0 and nums[i] >= nums[i + 1]:
            i -= 1
        if i >= 0:
            j = n - 1
            while nums[j] <= nums[i]:
                j -= 1
            nums[i], nums[j] = nums[j], nums[i]
        nums[i + 1:] = reversed(nums[i + 1:])

Complexity
#

Time O(n), space O(1).

Mistakes to Avoid
#

  • With duplicates, comparisons include equality.
  • Reverse the part after i, starting at i + 1.

Interview Explanation
#

I find the rightmost position smaller than its right neighbor, swap it with the smallest larger value to its right, and reverse the rest into increasing order; if none exists I reverse everything. Time O(n).

Related

LeetCode 11: Container With Most Water
·2 mins
LeetCode Medium Array Two-Pointers Greedy
LeetCode 11 note: start pointers at both ends and always move the shorter side; moving the taller side only narrows the width without raising the height
LeetCode 15: 3Sum
·2 mins
LeetCode Medium Array Two-Pointers Sorting
LeetCode 15 note: sort, fix the first number, and find the other two with converging pointers, skipping equal values at all three positions to avoid duplicate triplets
LeetCode 16: 3Sum Closest
·2 mins
LeetCode Medium Array Two-Pointers Sorting
LeetCode 16 note: sort, fix one number, and find the other two with converging pointers, comparing the distance abs(sum - target)
LeetCode 18: 4Sum
·2 mins
LeetCode Medium Array Two-Pointers Sorting
LeetCode 18 note: sort, fix the first two numbers with two loops, and converge pointers for the rest, skipping equal values at all four positions
LeetCode 33: Search in Rotated Sorted Array
·2 mins
LeetCode Medium Array Binary-Search
LeetCode 33 note: after rotation one side of mid is always sorted; check whether the target lies in it and search there, otherwise search the other side
LeetCode 34: Find First and Last Position of Element in Sorted Array
·2 mins
LeetCode Medium Array Binary-Search
LeetCode 34 note: two lower bounds: the first position >= target, and the first position >= target + 1 minus one