算法题丨Next Permutation
描述
Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.
If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).
The replacement must be in-place, do not allocate extra memory.
示例
Here are some examples. Inputs are in the left-hand column
and its corresponding outputs are in the right-hand column.
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
算法分析
难度:中
分析:这里需要跟大家介绍一下相关的几个概念:
排列(Arrangement),简单讲是从N个不同元素中取出M个,按照一定顺序排成一列,通常用A(M,N)表示。当M=N时,称为全排列(Permutation)。
例如对于一个集合A={1,2,3},首先获取全排列a1: 1,2,3;然后获取下一个排列a2: 1,3,2;
按此顺序,A的全排列如下,共6种:
a1: 1,2,3; a2: 1,3,2; a3: 2,1,3; a4: 2,3,1; a5: 3,1,2; a6: 3,2,1;
从数学角度讲,全排列的个数A(N,N)=(N)*(N-1)*...*2*1=N!,但从编程角度,如何获取所有排列?那么就必须按照某种顺序逐个获得下一个排列,通常按照升序顺序(字典序lexicographically)获得下一个排列。
对于给定的任意一种全排列,如果能求出下一个全排列的情况,那么求得所有全排列情况就容易了,也就是题目要求实现的下一个全排列算法(Next Permutation)。
思路:
设目前有一个集合的一种全排列情况A : 1,5,8,4,7,6,5,3,1,求取下一个排列的步骤如下:
/** Tips: next permuation based on the ascending order sort
* sketch :
* current: 1 5 8 4 7 6 5 3 1
* | | |
* find i----+ j +----end
* swap i and j :
* 1 5 8 5 7 6 4 3 1
* | | |
* j----+ i +----end
* reverse j+1 to end :
* 1 5 8 5 1 3 4 6 7
* | |
* find j----+ +----end
* */
具体方法为:
a)从后向前查找第一个相邻元素对(i,i+1),并且满足A[i] < A[i+1]。
易知,此时从j到end必然是降序。可以用反证法证明,请自行证明。
b)在[i+1,end)中寻找一个最小的j使其满足A[i]<A[j]。
由于[j,end)是降序的,所以必然存在一个j满足上面条件;并且可以从后向前查找第一个满足A[i]<A[j]关系的j,此时的j必是待找的j。
c)将i与j交换。
此时,i处变成比i大的最小元素,因为下一个全排列必须是与当前排列按照升序排序相邻的排列,故选择最小的元素替代i。
易知,交换后的[j,end)仍然满足降序排序。
d)逆置[j,end)
由于此时[j,end)是降序的,故将其逆置。最终获得下一全排序。
注意:如果在步骤a)找不到符合的相邻元素对,即此时i=begin,则说明当前[begin,end)为一个降序顺序,即无下一个全排列,于是将其逆置成升序。

代码示例(C#)
public void NextPermutation(int[] nums)
{
int i = nums.Length - 2;
//末尾向前查找,找到第一个i,使得A[i] < A[i+1]
while (i >= 0 && nums[i + 1] <= nums[i])
{
i--;
}
if (i >= 0)
{
//从i下标向后找第一个j,使得A[i]<A[j]
int j = nums.Length - 1;
while (j >= 0 && nums[j] <= nums[i])
{
j--;
}
//交换i,j
Swap(nums, i, j);
}
//逆置j之后的元素
Reverse(nums, i + 1, nums.Length);
}
//逆置排序
private void Reverse(int[] nums, int start, int end)
{
int i = start, j = end - 1;
while (i < j)
{
Swap(nums, i, j);
i++;
j--;
}
}
//交换
private void Swap(int[] nums, int i, int j)
{
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
复杂度
- 时间复杂度:O (n).
- 空间复杂度:O (1).
附录
算法题丨Next Permutation的更多相关文章
- LeetCode算法题-Letter Case Permutation(Java实现)
这是悦乐书的第315次更新,第336篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第184题(顺位题号是784).给定一个字符串S,将每个字母单独转换为小写或大写以创建另 ...
- 算法题丨Remove Duplicates from Sorted Array II
描述 Follow up for "Remove Duplicates": What if duplicates are allowed at most twice? 示例 Giv ...
- 算法题丨Longest Consecutive Sequence
描述 Given an unsorted array of integers, find the length of the longest consecutive elements sequence ...
- 算法题丨Two Sum
描述 Given an array of integers, return indices of the two numbers such that they add up to a specific ...
- 算法题丨3Sum
描述 Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all ...
- 算法题丨3Sum Closest
描述 Given an array S of n integers, find three integers in S such that the sum is closest to a given ...
- 算法题丨4Sum
描述 Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = ...
- 算法题丨Remove Element
描述 Given an array and a value, remove all instances of that value in-place and return the new length ...
- 算法题丨Move Zeroes
描述 Given an array nums, write a function to move all 0's to the end of it while maintaining the rela ...
随机推荐
- Jenkins集成Docker镜像实现自动发布
1. 思路&流程 Jenkins集成Docker镜像实现自动发布与Jenkins发布mavne项目思路一样总体流程 为:Jenkins 拉去远端源码 -- gitl实现应用打包 -- jenk ...
- canvas填充样式
填充样式主要针对fillStyle.fillStyle除了可以赋值为color,还可以赋值渐变色,包括线性渐变色和径向渐变色,还是和css3里的内容类似. 一.线性渐变 1.设置线性渐变的填充样式 设 ...
- [BZOJ 1297][SCOI2009]迷路
1297: [SCOI2009]迷路 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1418 Solved: 1017[Submit][Status ...
- Kettle 初始配置数据量类型资源库
PS:有段时间不使用Kettle了,但总遇到小伙伴问起,写一篇记录下. 文档使用版本:KETTLE 7.0 Kettle资源库可分为文件与数据库,文件型只需要配置好存放路径就行,这边介绍的是配置数据库 ...
- HIVE使用mysql作为外置数据库配置详情
Hive安装配置(mysql) 安装mysql hadoop$:sudo apt-get update hadoop$:sudo apt-get install mysql-server 启动mysq ...
- alpha-咸鱼冲刺day8-紫仪
总汇链接 一,合照 emmmmm.自然还是没有的. 二,项目燃尽图 三,项目进展 正在进行页面整合.然后还有注册跟登陆的功能完善-- 四,问题困难 数据流程大概是搞定了.不过语法不是很熟悉,然后还有各 ...
- 团队作业7——第二次项目冲刺(Beta版本计划及安排)
Beta版本冲刺 需要改进完善的功能 1.寻找BUG.并解决问题 2.界面的优化 下一阶段新增的功能' 1.个人信息头像上传 2.头像裁剪功能 需要改进的团队分工 1.之前产品的主要工作 ...
- 团队作业4——第一次项目冲刺(Alpha版本)
第一天http://www.cnblogs.com/ThinkAlone/p/7861070.html 第二天http://www.cnblogs.com/ThinkAlone/p/7861191.h ...
- 《高级软件测试》11.14.安装和运行Jira
今日任务完成情况如下: 小段:研究Jira在Linux的安装教程 小费:尝试在Ubuntu下安装Jira 小高:查阅了关于Jira软件的介绍和安装教程,下载准备明天安装,并学习使用 小王:注册Jira ...
- Apache自带 ab压测工具 Windows配置使用说明 - 随笔记录
我们先来了解一下ab工具的概念,摘自网络: ab是apache自带的压力测试工具.ab非常实用,它不仅可以对apache服务器进行网站访问压力测试,也可以对或其它类型的服务器进行压力测试.比如ngin ...