Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

The replacement must be in-place, do not allocate extra memory.

Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

【题目分析】

题目要求我们对一个数组进行变换,变换后的结果是按照字典序比当前结果大的值中最小的那一个。如果我们不能找到下一个permutation(即当前顺序是这些数字最大的字典序排列),那么直接给出一个逆序的结果。

【思路】

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

分析这几个例子我们发现,如果一段序列是完全降序排列的,那么它的字典序是最大的,即对于这个序列中任意相邻的两个数a和b,a>=b。如果存在这样相邻的两个数a < b,那么通过变换我们可以找到它的下一个permutation。比如1,2,3 -> 1,3,2 我们交换2和3即可得到下一个结果。但是考虑这样一个序列: 4,6,5,我们看到4比6小,如果我们交换3和6得到的结果是6,4,5,这是我们想要的结果吗?并不是,我们发现,虽然相邻的4和6相邻且6比4大,但是在6的右边,还存在一个5它比4大,但是它比6小,如果我们交换5和4,得到的结果才是正确的。

因此这个过程可以这样来描述:

1. 找到第一个相邻的元组(a,b),满足a < b;

2. 如果这样的元组不存在,则将数组逆序,程序结束;

3. 如果这样的元组存在,我们找到从b开始数组以后的数中比a大的最小的那一个c。

4. 交换a和c,然后把c之后所有的数逆序,得到最后的结果,返回;

例如:[4,6,5,3,2,1]

第一步:找到元组(4,6) 4 < 6

第二步:找到6之后比4大的元素中最小的那个:5

第三步:交换4和5->[5,6,4,3,2,1,1]

第四步:把5之后的数字逆序->[5,1,1,2,3,4,6]

通过上述几个步骤,我们能正确地找出任意一个序列的next greater permutation

【java代码】

 public class Solution {
     public void nextPermutation(int[] nums) {
         int len = nums.length;
         if(len < 2) return;
         //找到第一个降序的数
         int index;
         for(index = len - 2; index >= 0; index--){
             if(nums[index] < nums[index+1]) break;
         }
         //如果没有这样的数则直接返回逆序的结果
         if(index < 0){
             for(int i = 0,j = len - 1;i < j; i++, j--){
                 int temp = nums[i];
                 nums[i] = nums[j];
                 nums[j] = temp;
             }
             return;
         }
         //找到降序的数的右边比它大的数中最小的那一个
         int greater = index + 1;
         while(greater < len - 1 && nums[greater + 1] > nums[index]){
             greater ++;
         }
         //第一个降序的数和它右边比他大的最小的那个数交换
         int temp = nums[index];
         nums[index] = nums[greater];
         nums[greater] = temp;
         //第一个降序数位置之后所有数逆序,得到最后的结果
         for(int i = index + 1, j = len - 1; i < j; i++, j--){
             temp = nums[i];
             nums[i] = nums[j];
             nums[j] = temp;
         }
     }
 }

LeetCode OJ 31. Next Permutation的更多相关文章

  1. [Leetcode][Python]31: Next Permutation

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 31: Next Permutationhttps://oj.leetcode ...

  2. 【一天一道LeetCode】#31. Next Permutation

    一天一道LeetCode系列 (一)题目 Implement next permutation, which rearranges numbers into the lexicographically ...

  3. LeetCode 【31. Next Permutation】

    Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...

  4. leetcode problem 31 -- Next Permutation

    Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...

  5. 【LeetCode】31. Next Permutation

    Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...

  6. [array] leetcode - 31. Next Permutation - Medium

    leetcode - 31. Next Permutation - Medium descrition Implement next permutation, which rearranges num ...

  7. LeetCode - 31. Next Permutation

    31. Next Permutation Problem's Link ---------------------------------------------------------------- ...

  8. LeetCode OJ 题解

    博客搬至blog.csgrandeur.com,cnblogs不再更新. 新的题解会更新在新博客:http://blog.csgrandeur.com/2014/01/15/LeetCode-OJ-S ...

  9. 【LeetCode OJ】Interleaving String

    Problem Link: http://oj.leetcode.com/problems/interleaving-string/ Given s1, s2, s3, find whether s3 ...

随机推荐

  1. Redis五种数据结构简介

    Redis五种结构 1.String 可以是字符串,整数或者浮点数,对整个字符串或者字符串中的一部分执行操作,对整个整数或者浮点执行自增(increment)或者自减(decrement)操作. 字符 ...

  2. 学习Maven之Maven Surefire Plugin(JUnit篇)

    1.maven-surefire-plugin是个什么鬼? 如果你执行过mvn test或者执行其他maven命令时跑了测试用例,你就已经用过maven-surefire-plugin了.maven- ...

  3. 关于JS的总结

    =============================================事件:(事件必须小写) 用户的操作 onclick onmouseover onmouseout======= ...

  4. Winfrom 开发小技能

    1.放弃进度条.动态进度图片等方式实现用户体验优化方式(主要是优化用户等待体验),建议使用方式? 答:对于From或者Control而言,其提供了Cursor属性设置即可. 例如: this.Curs ...

  5. javascript、jQuery函数定义和调用方法

    一.javascript 1.var aaa=function(){...} var 方式定义的函数,不能先调用函数,后声明,只能先声明函数,然后调用. 2.function aaa(){...} f ...

  6. VR快速发展下,从业者如何把握机会?

      美国科技博客VentureBeat周末刊登赛斯·沙赫纳(Seth Schachner)的文章,分析了在虚拟现实快速发展的情况下,业内所面临的机会,以及如何把握这些机会.   沙赫纳是资深的数字战略 ...

  7. Batman崛起之地——Gotham

    刚看完FOX美剧<Gotham>第一集,很喜欢这种充满黑暗元素的影视剧,虽然是电视剧,却有电影的紧凑感和叙事分格. Gotham虚构了一个日渐堕落的美国城市,它充斥暴力.性等各种犯罪,普通 ...

  8. awr报告生成方法

    以上是在linux的oracle的命令截图. 如果是在unix的命令,则需要在命令前面加上\符号,变成了\@$ORACLE_HOME/rdbms/admin/awrrpt.sql

  9. listview去掉底部多出的边框黑色

    listview去掉底部多出的边框黑色 android:fadingEdge="none" //去掉listview黑色底边 listview.setDivider(null);

  10. 【转载】Java中如何写一段内存泄露的程序 &amp; ThreadLocal 介绍和使用

    可以参考这段文章: link A1:通过以下步骤可以很容易产生内存泄露(程序代码不能访问到某些对象,但是它们仍然保存在内存中): 上文中提到了使用ThreadLocal造成了内存泄露,但是写的不清不楚 ...