全排列问题

作者: littlersmall | 来源:发表于2016-01-25 14:17 被阅读102次

中午看到的一个题目。
求一个不重复字符串的全排列。

主要有递归,字典序等解决方案。然后想到stl里的next_permutation()函数,利用的便是字典序的方式。主要原理如下:

在当前序列中,从尾端往前寻找两个相邻元素,前一个记为i,后一个记为ii,并且满足i < ii。然后再从尾端寻找另一个元素j,如果满足i < *j,即将第i个元素与第j个元素对调,并将第ii个元素之后(包括ii)的所有元素颠倒排序,即求出下一个序列了。
在纸上画了半天,才把细节搞清楚了,确实很优雅的实现方式,很有启发性。

至于递归的方式,基于交换的思路,代码大体如下:

std::swap(val[i-1],val[k]);        
full_permutation(val,n,i+1);       
std::swap(val[i-1],val[k])  

看似很简单的三行,却很难模拟。
脑袋里想了半天,还是觉得很抽象。
不过这个算法最巧妙的地方还是利用字符串本身作为操作原型,没有引入其他结构存储字符串。

想来想去,觉得还是蛮复杂,遂自己写了一个python的版本,利用了yield特性,感觉好理解的多,如下:

def full_permutation(str):
    if (1 >= len(str)):
        yield str
    else:
        for i in full_permutation(str[1:]):
            for j in range(len(i) + 1):
                yield i[0:j] + str[0] + i[j:]   

只有7行。
思路也很简单,同样是利用递归的原理。
假如初始的字符串是a,字符串集合为{[a]}, 当加入b时,b的插入位置有a前和a后两个位置,插入后,新的字符串集合变为:
{[b, a], [a, b]}。当加入c时,对于[b, a],c的插入位置有3个,b前,a前,a后,也就是说:
[b, a] + c => [c, b, a], [b, c, a], [b, a, c],对于[a, b]也是同理。
概括来说,就是将每一个字符,插入每一个可能的位置。
(原文时间2013-9-16)

相关文章

  • 全排列问题

    中午看到的一个题目。求一个不重复字符串的全排列。 主要有递归,字典序等解决方案。然后想到stl里的next_per...

  • 全排列问题

    题目:给定一个 没有重复 数字的序列,返回其所有可能的全排列。 示例:输入: [1,2,3] 输出:[ [1,2,...

  • 全排列问题

    // 全排列.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。/*解题:1、递归式:填好怕...

  • 深度优先搜索

    全排列问题。 迷宫问题。

  • leetcode全排列问题

    1.leetcode47 题目: 给定一个可包含重复数字的序列,返回所有不重复的全排列。 示例: 输入:[1,1,...

  • 递归--全排列问题

    前置文章:递归算法:www.jianshu.com/p/703069f3ba3f . 递归问题有两个经典的...

  • 数组全排列问题

    最近看到剑指offer上一道数组全排列的题目,看似很简单,仔细分析一下,还是有点难以理解,特此在这拆解下,希望能够...

  • 全排列与n皇后的关系与递归实现

    全排列 对于全排列中的一般问题则是根据字典序从小到大输出指定数量或者序列的全排列。一个简单的问题则是:指定n个整数...

  • 全排列问题偷鸡做法

    全排列问题偷鸡摸狗做法用强大的(猥琐的)next_permutation 31. 下一个排列 46. 全排列 47...

  • 递归算法

    问题1:给定不重复的字符串,如123,给出全排列 分析:算123的全排列,首先算以1开头的23的全排列,然后再算以...

网友评论

    本文标题:全排列问题

    本文链接:https://www.haomeiwen.com/subject/kxxdkttx.html