题目

上一个排列

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

样例

给出排列[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. ECMAScript整理笔记(持续更新....)

    参考文献: ECMAScript Array:http://www.jimmycuadra.com/posts/ecmascript-5-array-methods ECMAScript5兼容展示大全 ...

  2. LINQ to XML(1)

    LINQ to XML可以两种方式和XML配合使用.第一种方式是作为简化的XML操作API,第二种方式是使用LINQ查询工具.下面我使用的是第二种方式. 主要内容:用LINQ查询语句对XML文件里的数 ...

  3. FastDFS4 + Ubuntu12安装及部署

    1. 安装libevent 如果需要使用http进行下载,需要安装这个组件. 2. 安装fastdfs 3. 配置fastdfs 4. 安装nginx 问题4.1:安装nginx启动后访问原先资源UR ...

  4. js中隐式类型转换测试

    javascript数据类型: 使用typeof可以返回的数据类型有六种 "number" , "string" ,  "boolean" ...

  5. java 反射的踩的一个坑

    今天工作的时候用到了一个反射.其业务简单描述为:系统启动时将需要定时调用的方法签名保存到数据库中,开启线程定时从数据库中读取对应的方法签名,通过反射生成实例后调用方法.完成一定的定时任务. 写到的方法 ...

  6. How to modify Code Comments[AX2012]

    // This is a framework class. Customizing this class may cause problems with future upgrades to the ...

  7. protected internal修饰符

    见过这样的修饰符,但是没有仔细考虑过,今天做一个小练习. 先给出一个链接,别人在网上讨论的:http://wenku.baidu.com/view/4023f65abe23482fb4da4cfe.h ...

  8. 小课堂Week10 例外处理设计的逆袭Part3

    小课堂Week10 例外处理设计的逆袭Part3 今天是<例外处理设计的逆袭>这本书阅读的第三天,也是最后一天,我们会主要通过实例,对Part2中提出的例外处理等级进行解读. Level1 ...

  9. 百度云盘demo

  10. Mysql 创建数据库表(删除,删除,插入)

    MySQL 创建数据表 创建MySQL数据表需要以下信息: 表名 表字段名 定义每个表字段 语法 以下为创建MySQL数据表的SQL通用语法: CREATE TABLE table_name (col ...