剑指Offer——字符串的排序

Question

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

Solution

abc的全排列是:abc, acb, bac, bca, cba, cab

可以看到字符串可以分为两部分,左边固定一个字符,然后右边的字符串之间交换。

然后再将第一个字符和后面的一个字符交换,保持第一个字符不动,右边的字符串之间交换。

可以看到这个是一个递归的过程。

Code

class Solution {
public:
    vector<string> Permutation(string str) {
        if (str.empty())
            return vector<string>();
        
        vector<string> res;
        Permutation(res, str, 0);
        // 字典序
        sort(res.begin(), res.end());
        
        return res;
    }
     
    void Permutation(vector<string> &array, string str, int begin) {
       if (begin == str.size() - 1)
           array.push_back(str);
        
        for (int i = begin; i < str.size(); i++) {
        	
        	// 和第一个字母相同的字符就不用再交换了
            if (i != begin && str[i] == str[begin])
                continue;
            
            swap(str[begin], str[i]);  // 交换
            
            Permutation(array, str, begin + 1);   // 递归
            
            swap(str[begin], str[i]);  // 再次交换回来
            
            /*
            需要两次交换的原因,举个例子
            abca, 第一个a和自己交换,遍历后面字符串
            abca, a和b交换,遍历,如果只交换一次的话,就是下面结果
            baca, 那么再次交换的时候就是b和c交换,不在是a和c交换了
            
            最后第一个a和最后一个a不用交换
            */
        }
    }
};
原文地址:https://www.cnblogs.com/zhonghuasong/p/7099977.html