剑指offer:面试题28——字符串的排列

剑指offer:面试题28——字符串的排列

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

输入描述:

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

思路:每次可以分为两步:

第一步是将第一个字符和后面每个字符依次交换

第二步是固定第一个字符,递归求后面字符的排列

为了去重,如果当前位字符和当前串第一位相同,不用交换直接进行下次递归

为了防止序列被递归交换后导致顺序改变从而影响后面的递归,发生某个序列被重复排列的情况,要使用两次交换,每次交换——递归——数值恢复原样——进行下次递归

class Solution {
public:
    void Permutation(string str,int begin,vector<string>&strArray)
    {
        //当串遍历到最后一位时调出并开始返回遍历
        if(begin==str.size()-1)
        {
            strArray.push_back(str);
        }
        else
        {
            for(int i=begin;i<str.size();i++)
            {
                //这里是当存在重复的字母时候,用于字符去重。即
                //aab与aab中的两个a交换无意义,所以如果遍历到哪个
                //字符与a相同则不用交换,直接调出
                if(i!=begin &&str[i]==str[begin])
                    continue;
                //开始交换
               swap(str[i],str[begin]);
                Permutation(str,begin+1,strArray);
                //为了防止发生重复,比如abc递归后变为acb,但防止后面
                //acb串的交换结果和当前结果重复,所以递归一次结束后,
                //要将开始位置的串再换回去
                swap(str[i],str[begin]);
            }
        }
    }
    public:
    vector<string> Permutation(string str) {
        vector <string>strArray;
        if(str.empty()) return strArray;
        Permutation(str,0,strArray);
        //这里是保证能够按照字典序输出
        sort(strArray.begin(),strArray.end());
        return strArray;
    }
   
};

猜你喜欢

转载自blog.csdn.net/MereX/article/details/89761564