zoukankan      html  css  js  c++  java
  • 【剑指Offer-分解让复杂问题简单化】面试题38:字符串的排列

    题目描述

    输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
    牛客网输入:输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
    注:牛客网的输入可能有字符重复,而书上是没有重复字符的。

    思路1

    可以模拟人来做排列的情形,比如3个字符a、b和c。第一个字符有3种选择:a、b或者c,当第一个字符确定之后,第二个字符有2种选择,当前两个字符确定之后,最后一个字符也确定了。使用循环和递归来模拟这一过程,代码如下:

    class Solution {
    public:
        vector<string> Permutation(string str) {
            vector<string> ans;
            if(str=="")
                return ans;
            
            int visit[str.length()];
            memset(visit, 0, sizeof(visit));
            string cur;
            PermutationCore(str, ans, cur, visit);
            ans = RemoveRepeat(ans);
            return ans;
        }
        
        void PermutationCore(string str, vector<string>& ans, string cur, int* visit){
            if(cur.length()==str.length()){
                ans.push_back(cur);
                return;
            }
            
            for(int i=0; i<str.length(); i++){
                if(!visit[i]){
                    visit[i] = 1;
                    cur+=str[i];
                    PermutationCore(str, ans, cur, visit);
                    cur = cur.substr(0, cur.length()-1);    //把前一步加的字符删掉
                    visit[i] = 0;
                }
            }
        }
        
        vector<string> RemoveRepeat(vector<string> ans){
            set<string> s;
            for(int i=0; i<ans.size(); i++)
                s.insert(ans[i]);
            
            vector<string> newAns;
            for(set<string>::iterator it=s.begin();it!=s.end(); it++)
                newAns.push_back(*it);
            return newAns;
        }
    };
    

    由于牛客网的输入可能包含重复数字,最终的输出中也包含重复的排列,所以添加了一个去重的函数RemoveRepeat,去重的思路是将所有排列放到set中,set中的元素都是唯一的,然后再把set中的元素放到vector中返回。

    思路2

    第2个思路就是书上的方法,将求整个字符串的排列分为2步:第一求所有可能出现在第一个位置的字符,也就是将第一个字符与后面所有字符交换;第二步,固定第一个字符,重复第一步的过程。代码如下:

    class Solution {
    public:
        vector<string> Permutation(string str) {
            vector<string> ans;
            if(str=="")
                return ans;
            
            int cur = 0;
            PermutationCore(str, ans, cur);
            ans = RemoveRepeat(ans);
            return ans;
        }
        
        void PermutationCore(string str, vector<string>& ans, int cur){
            if(cur==str.length()){
                ans.push_back(str);
                return;
            }
            
            for(int i=0; i<str.length(); i++){
                swap(str, i, cur);
                PermutationCore(str, ans, cur+1);
                swap(str, i, cur);
            }
        }
        
        void swap(string& str, int a, int b){
            char t = str[a];
            str[a] = str[b];
            str[b] = t;
        }
        
        vector<string> RemoveRepeat(vector<string> ans){
            set<string> s;
            for(int i=0; i<ans.size(); i++)
                s.insert(ans[i]);
            
            vector<string> newAns;
            for(set<string>::iterator it=s.begin();it!=s.end(); it++)
                newAns.push_back(*it);
            return newAns;
        }
    };
    
  • 相关阅读:
    SA 的参数
    superobject中 JavaToDelphiDateTime的使用
    关于Linux下进程间使用共享内存和信号量通信的时的编译问题
    Linux匿名管道与命名管道
    C++复数四则运算的实现
    C++类编程(一)const的使用
    读书会思考与学期总结
    xenomai安装
    Xenomai 安装准备工作
    Xenomai
  • 原文地址:https://www.cnblogs.com/flix/p/12500076.html
Copyright © 2011-2022 走看看