lintcode:previous permutation上一个排列
题目
上一个排列
给定一个整数数组来表示排列,找出其上一个排列。
给出排列[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的时候,原数字逆序就是答案,比如是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上一个排列的更多相关文章
- lintcode:next permutation下一个排列
题目 下一个排列 给定一个整数数组来表示排列,找出其之后的一个排列. 样例 给出排列[1,3,2,3],其下一个排列是[1,3,3,2] 给出排列[4,3,2,1],其下一个排列是[1,2,3,4] ...
- LinkCode 下一个排列、上一个排列
http://www.lintcode.com/zh-cn/problem/next-permutation-ii/# 原题 给定一个若干整数的排列,给出按正数大小进行字典序从小到大排序后的下一个排列 ...
- [LeetCode] Next Permutation 下一个排列
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
- Next Permutation 下一个排列
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
- [leetcode]31. Next Permutation下一个排列
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
- 【LeetCode每天一题】Next Permutation(下一个排列)
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
- [LeetCode] 31. Next Permutation 下一个排列
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
- 031 Next Permutation 下一个排列
实现获取下一个排列函数,这个算法需要将数字重新排列成字典序中数字更大的排列.如果不存在更大的排列,则重新将数字排列成最小的排列(即升序排列).修改必须是原地的,不开辟额外的内存空间.这是一些例子,输入 ...
- LintCode "Previous Permutation"
A reverse version of the Dictionary algorithm :) If you AC-ed "Next Permutation II", copy ...
随机推荐
- 获取iOS设备信息的编程接口
参考资料: [1] 博客园,iOS屏幕尺寸和分辨率了解 [2] 张兴业,获取手机信息(UIDevice.NSBundle.NSLocale), CSDN
- jQuery之$(document).ready()使用介绍
学习jQuery的第一件事是:如果你想要一个事件运行在你的页面上,你必须在$(document).ready()里调用这个事件 学习jQuery的第一件事是:如果你想要一个事件运行在你的页面上,你必须 ...
- jquery的相对父元素和相对文档定位示例代码
在开发jquery时候经常需要用到定位,有相对父元素定位和相对文档定位,本文为此总结下,有需要的朋友可以参考下 在开发jquery时候经常需要用到定位,这里概括两种定位: 1.相对父元素定位: $(& ...
- js拖拽3D立方体旋转
这段时间有点闲,所以就自己找些小玩意来练习练习.今天做了一个可以拖拽页面内空白位置3D立方体就会跟着转动的小例子,布局方面用到css3 3D转换技术,通过transform控制旋转实现的. 上个图 代 ...
- 实现Server.UrlEncode和Server.UrlDecode功能的js代码
<script> var EncodeURI = function(unzipStr,isCusEncode){ if(isCusEncode){ var zipArr ...
- ASP.NET对HTML元素进行权限控制(二)
这是这个权限控制的第一步,扫描界面把要分配权限的元素的信息获取出来存入到数据库中. 这一步分三小步: (1).标出界面所要分配权限的元素 (2).扫描界面获取所要分配权限的元素信息.(ID,标题,层级 ...
- VC2010 MFC文档类菜单快捷键无法加载问题
问题1. 在菜单中项中输入&Run\tF5, 运行显示Run,而不是Run F5. 问题2.在Accelerator中绑定了快捷键,但运行程序不起作用. 以上2中问题在VC++2008和VC+ ...
- MySQL SHOW 语句大全
常用的mysql show命令如下: 1.show databases; 显示mysql中所有数据库 2.show tables [from databases] ; 显示当前数 ...
- centos 6.4 apache开启gzip方法
系统概况,主机CentOS6.4 Apache2.4 php5.3.6 mysql5.5 开始:首先得确认apache是否已经加载了mod_deflate模块 1.httpd -M 在结果中查看是否 ...
- 实现iOS长时间后台的两种方法:Audiosession和VOIP(转)
分类: Iphone2013-01-24 14:03 986人阅读 评论(0) 收藏 举报 我们知道iOS开启后台任务后可以获得最多600秒的执行时间,而一些需要在后台下载或者与服务器保持连接的App ...