字符串的排列

题目描述

输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。

输入描述:

输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。

第一想法

  • 大小写的相同字母构成的字符串是否算同一个?比如说AAcaaC?
  • 无重复的字母排列是n!(按字典序输出)
  • 计算机中没有字典序就用ACSII码排序吧,但是aa和AA哪个排前面?
  • c++中的字符串如何使用
  • 提示中有动态规划,那么问题来了,动态规划是什么?

我的想法

像之前找路径那样的想法我已经想到了。在Vsc里面写了一些。

    void CA(string str){
        if(str.length() == 0){
            return ;
        }
        if(str.length() == 1){
            cstr.push_back(str[0]);
            fstr.push_back(cstr);
        }
        for(int i = 0; i < str.length(); ++i){
            cstr.push_back(str[i]);
            CA(delete_char(str,str[i]));
            cstr.pop_back();
        }
        return ;
    }
  • 就像那棵树一样,只不过一个是左右子树的push与pop,这个是有好多子树来for()

问题在于我选择的是新建空间,比如说{A,B,C}
A -> vec
然后要把A删掉的BC字符串放进去,写删除str中char的函数的时候出现了一些些问题,就看讨论区有没有更简易的办法.

看了讨论区

本来以为要自己手动实现sort函数,结果你告诉我可以直接调用???我懵了.


这是递归回溯法的解法.只是它是用的swap,我是新建再放进去的办法

class Solution {
public:
    vector<string> result;
    vector<string> Permutation(string str) {
        if(str.length() == 0)
            return result;
        Permutation(str, 0);
        //保证是字典序
        sort(result.begin(), result.end());
        return result;
    }
    void Permutation(string str, int begin){
        if(begin == str.length() - 1){
            result.push_back(str);
            return ;
        }
        for(int i = begin; str[i] != '\0';i++){
            //begin != i;因为首个交换的即是它本身,必定相等。
            //我们要找出之后相等的,跳过(重复的就不用交换了)。
            if(begin != i && str[i] == str[begin])
                continue;
            swap(str[i],str[begin]);
            Permutation(str,begin + 1);
            //因为在这个for中,是同一层的.之前交换过去的begin头还要交换回来
            //首元素,譬如说A,与B交换之后要交换回来再和C交换
            swap(str[i],str[begin]);
        }
    }
};

字典序全排列博客
https://www.cnblogs.com/pmars/archive/2013/12/04/3458289.html

以下是实现代码

class Solution {
public:
    /*
    设P是1~n的一个全排列:p=p1p2......pn=p1p2......pj-1pjpj+1......pk-1pkpk+1......pn
  1)从排列的右端开始,找出第一个比右边数字小的数字的序号j(j从左端开始计算),即 j=max{i|pi<pi+1}
  2)在pj的右边的数字中,找出所有比pj大的数中最小的数字pk,即 k=max{i|pi>pj}(右边的数从右至左是递增的,因此k是所有大于pj的数字中序号最大者)
  3)对换pj,pk
  4)再将pj+1......pk-1pkpk+1......pn倒转得到排列p'=p1p2.....pj-1pjpn.....pk+1pkpk-1.....pj+1,这就是排列p的下一个排列。
  */
class Solution {
public:
    vector<string> Permutation(string str) {
        vector<string> res;
        int len = str.length();
        if(len == 0)
            return res;
        else if(len == 1){
            res.push_back(str);
            return res;
        }
        str = sortStr(str);
        res.push_back(str);
        int left = -1, right = len - 1;
        while(true){
            left = -1;
            for(int i = len - 1; i > 0; --i){
                if(str[i - 1] < str[i]){
                    left = i - 1;
                    break;
                }
            }
            if(left == -1)
                break;
            for(int j = left + 1; j < len; ++j){
                if(str[j] > str[left])
                    right = j;
            }
            swap(str[left], str[right]);
            for(int i = left + 1,j = len - 1; i < j; i++,j--){
                swap(str[i], str[j]);
            }
            res.push_back(str);
        }
        return res;
    }

    string sortStr(string str){
        int len = str.length();
        char tmp;
        for(int i = 0; i < len - 1; ++i)
            for(int j = 0;j < len - 1 - i; ++j)
                if(str[j] > str[j + 1]){
                    tmp = str[j];
                    str[j] = str[j + 1];
                    str[j + 1] = tmp;
                }
        return str;
    }
};

字典排序

  • 从小到大排序
  • 从后往前,找到后面那个大于前面那个的位置,前面的下标为left,
  • 从left + 1开始向后找,找到最后一个大于left位置的下标为right
  • 交换left / right 的值,
  • 将 left后的序列逆序.
  • 得到的就是字典序列中原序列后一个序列.

eg.
12398745 ---- 45 然后变成12398754

12398754 ---3和9
找到 4交换 12498753
reverse 98753 是35789
12398754的后一个即为 12435789

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,717评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,501评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,311评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,417评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,500评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,538评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,557评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,310评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,759评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,065评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,233评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,909评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,548评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,172评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,420评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,103评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,098评论 2 352

推荐阅读更多精彩内容

  • 写在前面: 最近遇到了一道题涉及全排列的。记得之前在《剑指offer》上遇到了一道类似的题。因此今早把这道题翻了出...
    BlueSkyBlue阅读 616评论 0 0
  • 题目描述: 输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c...
    夏臻Rock阅读 2,523评论 0 0
  • 问题描述: 输入一个字符串,打印出该字符串的所有排列。例如,输入字符串”abc”,则输出有字符’a’,’b’,’c...
    dreamsfuture阅读 1,626评论 0 0
  • 题目:输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排...
    GIndoc阅读 125评论 0 0
  • rxjava2详细解释:http://blog.csdn.net/maplejaw_/article/detail...
    小小程序员jh阅读 149评论 0 0