leetcodeshautiriji-【31. 下一个排列】

113 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第24天,点击查看活动详情

题目描述

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

例如,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

题目元素

给定一个数组,将数组中的元素组合成各种不同的数组,然后将这些数组呈升序排列。返回给定数组的下一个数组,如果没有下一个数组则直接返回第一个数组。

解题思路

首先确定题意,对多个元素的组合数组的线性排列。 两个临界条件:

  • 整个数组呈升序排列,这个数组是最小的排列组合;
  • 整个数组呈降序排列,这个数组是最大的排列组合。

线性数组的下一个数组的获取方式:

从右向左遍历数组元素,找到数组不是降序的第一个节点位置,记为节点i。再从右向左遍历数组元素,找到第一个大于节点i的位置,记为节点j;交换i和j的元素,然后再对新的i节点的元素后面的元素进行降序排列,即获得给定数组的下一个数组排列。

代码实现

public static void nextPermutation(int[] nums) {
    int length = nums.length;
    // 临界条件
    if (length == 0 || length == 1) {
        return;
    }
    // 寻找第一个不是降序的节点i
    // 因为这里要一次获取两个元素,所以要多留1个位置
    int i = nums.length-2;
    while (i >= 0 && nums[i] >= nums[i+1]) {
        // 数组是降序
        i --;
    }
    // 查找第一个大于nums[i]的元素nums[j]
    int j = length-1;
    if (i >= 0) {
        while (j >= 0 && nums[i] >= nums[j]) {
            j--;
        }
        // 然后交换两个元素的位置
        swap(nums,i,j);
    }
    // 然后对i后面的数据降序排列
    sort(nums,i+1);
}

/**
 * 将给定数组进行升序排列
 *
 * @param nums 给定数组
 * @param i 需要排序的起始位置
 */
private static void sort(int[] nums, int i) {
    // 因为交换之后从i开始的元素都是呈升序排列,所以这里只需要交换前后元素的位置即可以将数组翻转呈升序数组
    int right = nums.length -1;
    while (i <= right && nums[i] > nums[right]) {
        swap(nums,i, right);
        i ++;
        right--;
    }
}

/**
 * 交换i和j两个元素的位置
 *
 * @param nums 给定数组
 * @param i 第一个位置
 * @param j 第二个位置
 */
private static void swap(int[] nums, int i, int j) {
    int temp = nums[i];
    nums[i] = nums[j];
    nums[j] = temp;
}