算法题丨Next Permutation

简介: 描述Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

描述

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)为一个降序顺序,即无下一个全排列,于是将其逆置成升序。
avatar

代码示例(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).

附录

img_8f0a90f3cbaa0e044fb8bf7b13c4317b.jpe

文章作者:原子蛋
文章出处:https://www.cnblogs.com/lizzie-xhu/
个人网站:https://www.lancel0t.cn/
个人博客:https://blog.lancel0t.cn/
微信公众号:原子蛋Live+
扫一扫左侧的二维码(或者长按识别二维码),关注本人微信公共号,获取更多资源。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

目录
相关文章
|
算法
算法:next数组的求法详解
算法:next数组的求法详解
766 0
算法:next数组的求法详解
|
存储 算法 BI
KMP算法(kmp) next数组算法解析
KMP算法(kmp) next数组算法解析
114 0
KMP算法(kmp) next数组算法解析
|
算法 Java
KMP算法 --- 深入理解next数组
在KMP算法中有个数组,叫做前缀数组,也有的叫next数组。 每一个子串有一个固定的next数组,它记录着字符串匹配过程中失配情况下可以向前多跳几个字符。 当然它描述的也是子串的对称程度,程度越高,值越大,当然之前可能出现再匹配的机会就更大。
1436 0
|
算法
KMP算法Next数组计算
KMP算法是在最近这两年的软件设计师考试中才出现的。2次都是让求Next函数的序列(其实是)。先看看题吧。 (2011年下半年上午题) (2012年上半年上午题) 其实做这个题很简单,我先说说这个题里的各种概念。
916 0
|
1月前
|
机器学习/深度学习 算法 生物认证
基于深度学习的人员指纹身份识别算法matlab仿真
基于深度学习的人员指纹身份识别算法matlab仿真
|
24天前
|
传感器 算法 计算机视觉
基于肤色模型和中值滤波的手部检测算法FPGA实现,包括tb测试文件和MATLAB辅助验证
该内容是关于一个基于肤色模型和中值滤波的手部检测算法的描述,包括算法的运行效果图和所使用的软件版本(matlab2022a, vivado2019.2)。算法分为肤色分割和中值滤波两步,其中肤色模型在YCbCr色彩空间定义,中值滤波用于去除噪声。提供了一段核心程序代码,用于处理图像数据并在FPGA上实现。最终,检测结果输出到&quot;hand.txt&quot;文件。
|
1月前
|
机器学习/深度学习 算法 计算机视觉
基于yolov2深度学习网络的视频手部检测算法matlab仿真
基于yolov2深度学习网络的视频手部检测算法matlab仿真
|
1月前
|
算法
【MATLAB】语音信号识别与处理:移动中位数滤波算法去噪及谱相减算法呈现频谱
【MATLAB】语音信号识别与处理:移动中位数滤波算法去噪及谱相减算法呈现频谱
20 2
|
1月前
|
算法
【MATLAB】语音信号识别与处理:一维信号NLM非局部均值滤波算法去噪及谱相减算法呈现频谱
【MATLAB】语音信号识别与处理:一维信号NLM非局部均值滤波算法去噪及谱相减算法呈现频谱
38 1