题目

上一个排列

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

样例

给出排列[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. hover和mouseover,mouseout的区别

    说道hover和mouseover,mouseout的区别,不得不联系到mouseenter,mouseleave. mouseover,mouseout是指鼠标指针在穿过/离开被选元素或其子元素时触 ...

  2. vs2008团队资源管理器安装步骤

    1.先装 VS2008TeamExplorer { NOTE: 要区分中英文版本Microsoft Visual Studio 2008 Service Pack 1 (iso) VS2008SP1C ...

  3. CDH JPS 出现没有名字的进程

    jps 时出现没有名字的进程 或者process information unavailable 把服务关掉,执行一下 rm -rf /tmp/hsperfdata_* 再重启就好了.

  4. Vim一些实用的用法

    打开多个文件: 1.vim还没有启动的时候:在终端里输入 vim file1 file2 ... filen便可以打开所有想要打开的文件2.vim已经启动输入:open file可以再打开一个文件,并 ...

  5. CentOS如何分区

    安装Linux CentOS时,需要在硬盘建立CentOS使用的分区,在大多情况下,至少需要为CentOS建立以下3个分区. (1)/boot分区(不是必须的):/boot分区用于引导系统,它包含了操 ...

  6. Winfrom 抓取web页面内容代码

    WebRequest request = WebRequest.Create("http://1.bjapp.sinaapp.com/play.php?a=" + PageUrl) ...

  7. libnuma.so.1()(64bit) is needed by mysql-community-server-5.7.9-1.el6.x86_64

    版本:5.7.9 新装的CentOS 6.3 安装MySQL 5.7.9 出现的问题 1.首先卸载系统自带的mysql 5.1的包    yum   -y  remove   mysql-libs-5 ...

  8. CentOS 7.0安装MPlayer

    自带的播放器不管rmvb还是mp4都不能播放,也搜索不到解码器. CentOS7epel装不上所以也没有rpmfusion,所以决定自己编译mplayer 首先是要获取源代码. 首先是主程序的源代码. ...

  9. floor舍去法取整

    $int = 0.99999999999999999; echo floor($int); // returns 1 $int = 0.9999999999999999; echo floor($in ...

  10. phpcms v9 企业黄页系统发布没有表单出现的解决方案

    第一种解决方案: 第一步:把yp_UTF8压缩文件解压得到:api.caches.phpcms.statics四个文件夹. 第二步:把这四个文件夹分别覆盖已安装好的phpcms系统根目录下的文件夹.这 ...