题目

上一个排列

给定一个整数数组来表示排列,找出其上一个排列。

样例

给出排列[1,3,2,3],其上一个排列是[1,2,3,3]

给出排列[1,2,3,4],其上一个排列是[4,3,2,1]

注意

排列中可能包含重复的整数

解题

排列的特征

123 的排列依次是:123、132、213、231、312、321

要点:

1.整体来说是升序的

2.对一个数而言,各位数字中,大的数字越靠后,这个数在排列的位置越靠前,同样,小的数字越靠前,这个数在排列的位置越靠前

参考1 参考2 上面说的方法好像都是一样的

1.对每位数字,先找到从右到左递减序列的前一个位置

2.当这个位置是-1的时候,原数字逆序就是答案,比如是12345,右到左递减序列的前一个位置是 -1  ,原数字直接逆序:54321 就是答案,注意这里的排列要是和循环的,不然第一个数没有前一个数了

3.当这个位置不是-1  说明原数字不是排列中的第一个数

设这个位置是peakInd,这个位置的数是nums[peakInd] 。我们知道nums[peakInd] > nums[peakInd +1]     但是不是nums中从 peakInd 到nums.size() -1 内的数都一定小于nums[peakInd],我们找到第一个nums[swapInd] > nums[peakInd] 并将这两个数进行交换

4.交换之后从peakInd + 1 到nums.size() -1 这里的数也一定是非递减的,对这部分的数逆序后,整体的数就是答案了。

比如:40712389 右到左递减序列的前一个位置是peakInd = 2 ,3到7内左到右第一个大于7的数是8,其位置是6,交换这个两个位置的数后:40812379,下面在对3 到7位置内的数进行逆序后:40897321.就是答案了。

这里的第一点就是,先找到右到左的递减序列,这个递减序列“逆序”后,左到右就是递增的序列,上面递减序列数字组成的最大的数。

同时要对找到的递减序列前一个数,和该递减序列的第一个大于它的数进行交换,至于为什么,我不是很理解,最后逆序就是上一行刚说的了。

Java

public class Solution {
/**
* @param nums: A list of integers
* @return: A list of integers that's previous permuation
*/
public ArrayList<Integer> previousPermuation(ArrayList<Integer> nums) {
// write your code
int peakInd = nums.size() - 1;
// 从后向前走,找到第一个nums[peakInd - 1] > nums[peakInd] 退出
// 后向前走 降序序列的最后一个位置跳出
while(peakInd > 0 && nums.get(peakInd - 1) <= nums.get(peakInd)){
peakInd--;
}
//降序序列的前一个位置
peakInd--;
if(peakInd >= 0){
int swapInd = peakInd + 1;
while(swapInd< nums.size()
&& nums.get(swapInd) < nums.get(peakInd)){
swapInd++;
}
swapInd--;
int tmp = nums.get(swapInd);
nums.set(swapInd,nums.get(peakInd));
nums.set(peakInd,tmp);
}
int left = peakInd + 1;
int right = nums.size() - 1;
while(left < right){
int tmp = nums.get(left);
nums.set(left,nums.get(right));
nums.set(right,tmp);
left ++;
right --;
}
return nums;
}
}

Java Code

凭借刚做的印象有写了一遍

public class Solution {
/**
* @param nums: A list of integers
* @return: A list of integers that's previous permuation
*/
public ArrayList<Integer> previousPermuation(ArrayList<Integer> nums) {
// write your code
int peakInd = nums.size() - 1;
while(peakInd >0 && nums.get(peakInd)>=nums.get(peakInd-1)){
peakInd --;
}
peakInd --;
if(peakInd >=0){
int swapInd = peakInd + 1;
while(swapInd < nums.size() && nums.get(peakInd) >nums.get(swapInd)){
swapInd +=1;
}
swapInd--;
int tmp = nums.get(swapInd);
nums.set(swapInd,nums.get(peakInd));
nums.set(peakInd,tmp);
}
int left = peakInd + 1;
int right = nums.size() - 1;
while(left < right){
int tmp = nums.get(left);
nums.set(left,nums.get(right));
nums.set(right,tmp);
left++;
right--;
}
return nums;
}
}

Java Code

Python

class Solution:
# @param num : a list of integer
# @return : a list of integer
def previousPermuation(self, nums):
# write your code here
peakInd = len(nums) - 1 while peakInd>0 and nums[peakInd] >= nums[peakInd - 1]:
peakInd -=1
peakInd -=1
if peakInd >=0:
swapInd = peakInd + 1
while swapInd< len(nums) and nums[peakInd] > nums[swapInd]:
swapInd +=1
swapInd -=1
nums[swapInd],nums[peakInd] =nums[peakInd] ,nums[swapInd]
left = peakInd + 1
right = len(nums) - 1
while left< right:
nums[left],nums[right] = nums[right],nums[left]
left +=1
right -=1
return nums

Python Code

lintcode:previous permutation上一个排列的更多相关文章

  1. lintcode:next permutation下一个排列

    题目 下一个排列 给定一个整数数组来表示排列,找出其之后的一个排列. 样例 给出排列[1,3,2,3],其下一个排列是[1,3,3,2] 给出排列[4,3,2,1],其下一个排列是[1,2,3,4] ...

  2. LinkCode 下一个排列、上一个排列

    http://www.lintcode.com/zh-cn/problem/next-permutation-ii/# 原题 给定一个若干整数的排列,给出按正数大小进行字典序从小到大排序后的下一个排列 ...

  3. [LeetCode] Next Permutation 下一个排列

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

  4. 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. 【LeetCode每天一题】Next Permutation(下一个排列)

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

  7. [LeetCode] 31. Next Permutation 下一个排列

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

  8. 031 Next Permutation 下一个排列

    实现获取下一个排列函数,这个算法需要将数字重新排列成字典序中数字更大的排列.如果不存在更大的排列,则重新将数字排列成最小的排列(即升序排列).修改必须是原地的,不开辟额外的内存空间.这是一些例子,输入 ...

  9. LintCode "Previous Permutation"

    A reverse version of the Dictionary algorithm :) If you AC-ed "Next Permutation II", copy ...

随机推荐

  1. 基础学习总结(八)--HttpClient

    在Android开发中,Android SDK附带了Apache的HttpClient,它是一个完善的客户端.它提供了对HTTP协议的全面支持,可以使用HttpClient的对象来执行HTTP GET ...

  2. 【Qt】Qt之密码框不可选中、复制、粘贴、无右键菜单等【转】

    简述 在做用户登录.修改密码的时候,往往会用到密码框,其中一些功能要求与普通的输入框不同,例如:不能选中.复制.粘贴.无右键菜单等功能,当然设置密码不可见是必须的! 下面介绍两种方式来实现相同的效果. ...

  3. .NET SOCKET通信编程

    1 using System; 2 using System.Net; 3 using System.Net.Sockets; 4 using System.Text; 5 6 public clas ...

  4. Oracle 动态视图5 V$SESSION_LONGOPS

    一.视图V$SESSION_LONGOPS显示运行超过6秒的操作的状态.包括备份,恢复,统计信息收集,查询等等 Column Datatype Description SID NUMBER Sessi ...

  5. 虚拟机开机提示:This virtual machine appears to be in use

    [原因]:由于电脑非正常关机导致,重新启动虚拟机就会出现This virtual machine appears to be in use的提示.[解决方法]:到虚拟机的安装目录下删除所有.lck的目 ...

  6. Thinkphp常用的方法和技巧(转)

    2012年09月26日 Thinkphp 里一些常用方法和技巧的整理,包括常用的快捷键以及在程序开发时用到的一些实用方法,关于快捷键用得不是很熟练,总之,掌握这些方法和技巧,对于我们开发 thinkp ...

  7. php 彩票类 lottery

    <?php /* * For the full copyright and license information, please view the LICENSE * file that wa ...

  8. iOS的影片播放 MediaPlayer 和 AVPlayer(转)

    分类: Iphone2013-01-28 16:19 5230人阅读 评论(0) 收藏 举报 在iOS開發上,如果遇到需要播放影片,如開機動畫…,我們很習慣地會使用MediaPlayer來播放影片,因 ...

  9. linux 命令grep

    linux 命令grep grep命令用来搜索文本,或从给定的文件中搜索行内包含了给定字符串或单词的文件.通常来说,grep显示匹配的行.使用grep来搜索包括一个或多个正则表达式匹配到的文本行,然后 ...

  10. 活动图 Activity Diagram

    活动图 可通过一系列操作将业务流程或软件进程以工作流的形式显示出来.这些操作可以由人.软件组件或计算机来执行. 使用活动图可以描述多种类型的流程,如下: 1.用户和您的系统之间的业务流程或工作流. 2 ...