剑指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; } };