题目

上一个排列

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

样例

给出排列[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. Linux mkisofs 创建光盘镜像文件(Linux指令学习笔记)

    mkisofs命令 创建光盘文件的系统的命令是mkisofs.光盘系统有多种格式,利用Linux系统提供的光盘文件系统创建 命令mkisofs,可以创建多种iso9660文件系统. 我们一般不用mki ...

  2. 设置Linux时间 同步时间

    date命令将日期设置为2014年6月18日 ----   date -s 06/18/14 将时间设置为14点20分50秒 ----   date -s 14:20:50 将时间设置为2014年6月 ...

  3. JQuery 表格 隔行换色 和鼠标滑过的样式

    $(document).ready(function () { $(".Pub_TB tbody tr:even td").css("background-color&q ...

  4. 【原】ComboBoxety用户输入自动匹配

    //在界面构造函数里加入下面两行代码 this.cbbDepartureAirport.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode ...

  5. 安卓4.0下rem显示不正常的问题

    在项目中使用了rem为单位,结果在Oppo和4.0下某些浏览器rem工作不正常,font-size计算出来的px总是大于预期的值,因此加了个Hack var docEl = doc.documentE ...

  6. 安装gitolite,并ssh公钥无密码登录

    安装gitolite,并ssh公钥无密码登录 gitolite是管理git版本库的一种方案,它将git版本库的管理信息放在了一个特殊git版本库里.gitolite与linux操作系统集成了,需要使用 ...

  7. Win7构造wifi热点【Written By KillerLegend】

    1:Win+R打开DOS,输入以下命令然后回车,不要关闭该DOS窗口: netsh wlan set hostednetwork  mode = allow ssid =你的wifi热点名字  key ...

  8. openerp经典收藏 深入理解工作流(Workflow)(转载)

    深入理解工作流(Workflow) 原文:http://shine-it.net/index.php/topic,2494.0.html 一.工作流定义:<?xml version=" ...

  9. Jquery LigerUI框架学习(二)之Tree于Tab标签实现iframe功能

    LigerUI框架Tree于Tab标签动态使用,当点击Tree后动态创建Tab标签,和通常用的iframe框架功能类似 Tree中的关键代码 //Tree初始化 $("#tree1" ...

  10. FastLoad错误 — SELECT Failed. 2652

    SELECT * FROM   teradata_education. emp_fl;     在做查询时碰到2652错误.   SELECT Failed. 2652: Operation not ...