题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
理解:为什么不加return,因为按照正常的执行流程,for循环三次之后也会退出程序,而if tmp.size == str.size,也是等于sz就退出,所以不加return也是对的。
如果是无重复元素求全排列,是不是就可以去掉判重的数组visited,for循环里面的if判断是不是就不需要了?
答:不能去掉,这个版本是通用的,既可以解决无重复的也可以解决有重复元素的全排列问题,如果去掉了for里面的判断,会导致死循环,不断的往里面加第一个元素a,因为程序中每次i都会从0开始
也就是说每次都会压第一个元素,加上那个去重的判断后,访问过的第一个元素a就会标记为true,会continue。所以以前理解的定义一个start,使得每次递归的时候i = start就是这个原因。
class Solution { public: void helper(string str,vector<string> &res,string &tmp,vector<bool> &visited){ if(tmp.size() == str.size()){ res.push_back(tmp); //return; } for(int i = 0;i < str.size();++i){ if(i != 0 && str[i] == str[i - 1] && (visited[i - 1] == false) || (visited[i] == true)){ continue; } visited[i] = true; tmp.push_back(str[i]); helper(str,res,tmp,visited); tmp.pop_back(); visited[i] = false; } } vector<string> Permutation(string str) { if(str.empty()){ return {}; } vector<string> res; vector<bool> visited(str.size(),false); string tmp; helper(str,res,tmp,visited); return res; } };