下一个排列 - LeetCode 热题 99

发布于:2024-06-20 ⋅ 阅读:(121) ⋅ 点赞:(0)

大家好!我是曾续缘🤗

今天是《LeetCode 热题 100》系列

发车第 99 天

技巧第 4 题

❤️点赞 👍 收藏 ⭐再看,养成习惯

下一个排列

整数数组的一个 排列  就是将其所有成员以序列或线性顺序排列。

  • 例如,arr = [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3][1,3,2][3,1,2][2,3,1]

整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。

  • 例如,arr = [1,2,3] 的下一个排列是 [1,3,2]
  • 类似地,arr = [2,3,1] 的下一个排列是 [3,1,2]
  • arr = [3,2,1] 的下一个排列是 [1,2,3] ,因为 [3,2,1] 不存在一个字典序更大的排列。

给你一个整数数组 nums ,找出 nums 的下一个排列。

必须 原地 修改,只允许使用额外常数空间。

示例 1:

输入:nums = [1,2,3]
输出:[1,3,2]

示例 2:

输入:nums = [3,2,1]
输出:[1,2,3]

示例 3:

输入:nums = [1,1,5]
输出:[1,5,1]

提示:

  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 100
难度:💖💖

解题方法

下一个排列是一个经典的算法问题,要求我们找出给定整数数组的下一个字典序更大的排列。如果当前排列已经是最大可能的排列,那么我们需要找到最小的排列,即所有数字按照升序排列。这个问题要求我们原地修改数组,并且只能使用常数空间。

解题步骤

步骤1:从后向前查找递减序列

我们从数组的最后一个元素开始向前查找,找到第一个满足nums[i] < nums[i+1]的元素nums[i]。这个元素是可以增大的最小值了。

步骤2:找到比nums[i]大的最小元素

从数组的最后一个元素开始向前查找,找到第一个满足nums[j] > nums[i]的元素nums[j]。这个元素将会和nums[i]交换。

步骤3:交换nums[i]nums[j]

交换nums[i]nums[j],这样就得到了一个新的排列,nums[i]变大了,变大的尽可能的小,为nums[j]。但还没有结束。

步骤4:反转nums[i+1]到末尾的序列

由于nums[i+1]到数组末尾的序列是降序排列的,我们需要将其反转,使其成为升序排列,变得 最小。

Code

public class Solution {
    public void nextPermutation(int[] nums) {
        // 从后向前查找递减序列
        int i = nums.length - 2;
        while (i >= 0 && nums[i] >= nums[i + 1]) {
            i--;
        }
        // 如果找到递减序列,则进行下一步查找
        if (i >= 0) {
            // 找到比nums[i]大的最小元素
            int j = nums.length - 1;
            while (j >= 0 && nums[i] >= nums[j]) {
                j--;
            }
            // 交换nums[i]和nums[j]
            swap(nums, i, j);
        }
        // 反转nums[i+1]到末尾的序列
        reverse(nums, i + 1, nums.length - 1);
    }

    private void swap(int[] arr, int i, int j) {
        // 交换两个元素
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    private void reverse(int[] arr, int start, int end) {
        // 反转数组的一部分
        while (start < end) {
            swap(arr, start, end);
            start++;
            end--;
        }
    }
}


网站公告

今日签到

点亮在社区的每一天
去签到