剑指offer 字符串的排列

题目描述

输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
思路:本题就是permutations有重复元素的,求整个字符串的排列,可以看成两步,首先求出所有可能出现在第一个位置的字符,即把第一个字符和后面的所有字符进行交换。剑指offer P154。visited数组就是保持该元素是否被访问过,本题目因为有重复元素,所以首先要进行排序。
if(i != 0 && str[i] == str[i - 1] && visited[i - 1] == 0 || visited[i] == 1){
     continue;
 }
i != 0 && str[i] == str[i - 1] && visited[i - 1] == 0相同元素必须要访问前一个元素之后,才能访问下一个元素。
visited[i] == 1该元素如果已经访问了就不需要再访问了。
permutation是求排列问题,所以每次i都是从0开始的。但是subset是求子集问题,所以每次开始都是i = start开始的。
class Solution {
public:
    void helper(vector<string> &result,string &str,string &tmp,vector<int> &visited){
        if(tmp.size() == str.size()){
            result.push_back(tmp);
            return;
        }
        for(int i = 0;i < str.size();++i){
            if(i != 0 && str[i] == str[i - 1] && visited[i - 1] == 0 || visited[i] == 1){
                continue;
            }
            visited[i] = 1;
            tmp.push_back(str[i]);
            helper(result,str,tmp,visited);
            tmp.pop_back();
            visited[i] = 0;
        }
    }
    vector<string> Permutation(string str) {
        vector<string> result;
       if(str.size() == 0){
           return result;
       }
       string tmp;
       sort(str.begin(),str.end());
       vector<int> visited(str.size(),0);
       helper(result,str,tmp,visited);
       return result;
    }
};


原文地址:https://www.cnblogs.com/dingxiaoqiang/p/7475718.html