返回

下一个排列算法和技巧

前端

理解问题

在「leetcode」31 - 下一个排列问题中,我们给定一个整数数组arr。我们需要找到arr的下一个排列。下一个排列是指arr中数字的下一个字典序排列。例如,arr = [1,2,3],其下一个排列是[1,3,2]。

解决方案

找到下一个排列的算法如下:

  1. 从后往前遍历数组,找到第一个数字arr[i]使得arr[i] < arr[i+1]。
  2. 如果没有这样的数字,则说明arr已经处于字典序的最后一个排列,此时我们需要将arr反转为字典序的第一个排列。
  3. 在找到第一个arr[i] < arr[i+1]的数字后,我们需要找到arr[i+1]到arr[n-1]中的最小数字arr[j]使得arr[j] > arr[i]。
  4. 将arr[i]和arr[j]交换位置。
  5. 将arr[i+1]到arr[n-1]排序。
  6. 返回排序后的arr。

代码实现

def nextPermutation(nums):
  """
  Find the next permutation of a given array of integers.

  Args:
    nums: A list of integers.

  Returns:
    A list of integers representing the next permutation of nums.
  """

  # Find the first number from the end that is smaller than the next number.
  i = len(nums) - 2
  while i >= 0 and nums[i] >= nums[i + 1]:
    i -= 1

  # If no such number is found, then the array is in the last permutation.
  if i < 0:
    nums.reverse()
    return nums

  # Find the smallest number from the end that is greater than nums[i].
  j = len(nums) - 1
  while j > i and nums[j] <= nums[i]:
    j -= 1

  # Swap nums[i] and nums[j].
  nums[i], nums[j] = nums[j], nums[i]

  # Reverse the subarray from nums[i+1] to the end.
  nums[i + 1:] = reversed(nums[i + 1:])

  # Return the resulting array.
  return nums


# Example usage:
nums = [1, 2, 3]
next_permutation = nextPermutation(nums)
print(next_permutation)  # [1, 3, 2]

时间复杂度

算法的时间复杂度为O(n),其中n是数组arr的长度。

空间复杂度

算法的空间复杂度为O(1),因为我们只需要使用常数个额外变量。