Go实现字符串全排列字典序排列详解

本文详细讲解了如何用Go语言实现字符串的全排列,并按字典序排列。首先介绍了字典序的概念,然后通过举例说明如何找到下一个排列,接着详细阐述了代码逻辑和实现步骤,包括找到排列中的最后一个升序首位、交换元素以及翻转部分序列。最后,文章引用了相关书籍和资源供读者进一步学习。
人生就是一场游戏,我们不停的打怪通关,有的时候这个怪物是自己。————陌无崖

不忘初心,砥砺前行 

作者 | 陌无崖

转载请联系授权 

字典序

百度百科

在数学中,字典或词典顺序(也称为词汇顺序,字典顺序,字母顺序或词典顺序)是基于字母顺序排列的单词按字母顺序排列的方法

维基百科

给定两个偏序集A和B,(a,b)和(a′,b′)属于笛卡尔积 A × B,则字典序定义为(a,b) ≤ (a′,b′) 当且仅当 a < a′ 或 (a = a′ 且 b ≤ b′).

简单理解

在我们进行查找英文词典的时候,我们如何进行查找,我们会依次的进行从首字母进行查找,那我们逆向思维,如果我们想要这样的查找我们应该怎么去存储我们的英语,不同的英语如何进行排序呢?对于两个英语abc 和 acb显然我们先比较我们的a,发现相同,寻找各自的第二个字符,谁小,我们就把小的放在前面。按照这样的方式我们强制规定了一个顺序。

题目思路

假定现有字符串(A)x(B),它的下一个排列是:(A)y(B’),其中A、B和B’是“字符串”(可能为空),x和y是“字符”,前缀相同,都是A,且一定有y > x。那么,为使下一个排列字典顺序尽可能小,必有:

  • A尽可能长

  • y尽可能小

  • B’里的字符按由小到大递增排列
    那么如何找x和y呢?

举例

现在我们要找21543的下一个排列,我们可以从左至右逐个扫描每个数,看哪个能增大(至于如何判定能增大,是根据如果一个数右面有比它大的数存在,那么这个数就能增大),我们可以看到最后一个能增大的数是:x = 1。
而1应该增大到多少?1能增大到它右面比它大的那一系列数中最小的那个数,即:y = 3,故此时21543的下一个排列应该变为23xxx,显然 xxx(对应之前的B’)应由小到大排,于是我们最终找到“21543”大但字典顺序尽量小的23145,找到的23145刚好比21543大。

代码逻辑

定义升序
相邻两个位置ai < ai+1,ai 称作该升序的首位
步骤(二找、一交换、一翻转)

  • 找到排列中最后(最右)一个升序的首位位置i,x = a[i]

  • 找到排列中第i位右边最后一个比a[i] 大的位置j,y = a[j]

  • 交换x,y

  • 把第(i+ 1)位到最后的部分翻转

注意
在代码逻辑的第二步骤中我们强调了最后一个,但是在举例中的我们强调1要增加到比它右面比它大的那一系列数中最小的那个数,这里并不冲突,因为我们在进行步骤1的时候,因为强调了最后一组a[i]<a[i+1]因此,在i位置之后,我们的排列一定是降序的,因此最后一个比a[i]大的数也一定是最小的。

代码实现

func CalAllPermutation(str string) string {

    // 记录首位置
    i := 0
    // 记录末位置
    j := 0
    for i = len(str) - 2; i >= 0; i-- {
        if str[i] <= str[i+1] {
            break
        }
    }
    if i < 0 {
        return str
    }
    //
    for j = len(str) - 1; j > i; j-- {
        if str[i] < str[j] {
            break
        }
    }
    str1 := []rune(str)
    // 交换
    str1[i], str1[j] = str1[j], str1[i]
    // 赋值
    str = string(str1)
    // 固定前面的字符串
    s := str[:(i + 1)]
    // 反转后面的字符串进行拼接
    s += ResverString(str[(i + 1):])
    return s

}
func ResverString(str string) string {
    r := []rune(str)
    j := len(r) - 1
    for i := 0; i < len(r)/2; i++ {
        r[i], r[j] = r[j], r[i]
        j--
    }
    return string(r)
}

参考

《编程之法:面试和算法心得》——作者:July

关注我试试回复以下关键词

go 微服务 ppt

大数据 书籍 资料 


END

今日推荐阅读

RabbitMQ系列笔记广播模式和路由模式 
RabbitMQ系列笔记入门篇

RabbitMQ系列笔记work模式

RabbitMQ系列笔记work模式

protoc语法详解及结合grpc定义服务

Golang中Model的使用

基于Nginx和Consul构建高可用及自动发现的Docker服务架构

▼关注我,一起成长

    主要分享 学习心得、笔记、随笔▼

    

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值