Leetcode31. 下一个排列

本文详细解析了LeetCode第31题“下一个排列”的算法思路及实现,介绍了如何通过一次遍历找到升序序列前的最大数,并通过交换和反转操作生成下一个字典序排列。

Leetcode31. 下一个排列

题目:
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。

1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

题解:
1.对数组nums从后往前查找,找到第一个比后面所有元素都小的元素位置 iii;
2.如果 i=0i=0i=0,说明数组是降序排列的,那么将数组反转一下得到结果;
3.如果 i≠0i\neq0i=0,从后往前遍历数组,找到第一个比nums(i)nums(i)nums(i)大的值所在的索引j,将i和j位置的数据互换位置;再对索引是 i+1i+1i+1 到数组的最后的数据进行反转即可。
java代码:

  public static int[] nextPermutation(int[] nums) {
        int i = nums.length - 2;
        while (i >= 0 && nums[i] > nums[i + 1]) {
            i--;
        }
        if (i >= 0) {
            int j = nums.length - 1;
            while (j >= 0 && nums[i] > nums[j]) {
                j--;
            }
            int tmp = nums[i];
            nums[i] = nums[j];
            nums[j] = tmp;
        }
        int left = i + 1;
        int right = nums.length - 1;
        while (left < right) {
            int tmp1 = nums[left];
            nums[left] = nums[right];
            nums[right] = tmp1;
            left++;
            right--;
        }
        return nums;
    }

scala代码:

 /**
    *
    * @param nums
    */
  def nextPermutation(nums: Array[Int]): Array[Int] = {
    var i = nums.length - 2
    while (i >= 0 && nums(i + 1) <= nums(i)) {
      i = i - 1
    }
    //数组是降序排列
    if (i == -1) {
      var a = 0
      var b = nums.length - 1
      while (a < b) {
        //当找到第一个比nums(i)大的值时,交换两个值的位置
        val tmp = nums(a)
        nums(a) = nums(b)
        nums(b) = tmp
        a = a + 1
        b = b - 1
      }
    } else {
      var j = nums.length - 1
      while (j >= 0 && nums(i) > nums(j)) {
        j = j - 1
      }
      //当找到第一个比nums(i)大的值时,交换两个值的位置
      val tmp = nums(i)
      nums(i) = nums(j)
      nums(j) = tmp
      //再交换i位置之后的数据,按照从小到大排列
      var k = nums.length - 1
      while (i + 1 < k) {
        val tmp = nums(i + 1)
        nums(i + 1) = nums(k)
        nums(k) = tmp
        i = i + 1
        k = k - 1
      }
    }
    nums
  }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值