
class Solution { public: set<string> s; bool vis[10]; void dfs(int k, string tiles, string str) { if(k == 0) s.insert(str); int len = tiles.length(); for(int i = 0; i < len; i++) { if(vis[i]) continue; vis[i] = 1; dfs(k - 1, tiles, str + tiles[i]); vis[i] = 0; } } int numTilePossibilities(string tiles) { int len = tiles.length(); for(int i = 1; i <= len; i++) { memset(vis, 0, sizeof(vis)); dfs(i, tiles, ""); } return s.size(); } };
dfs
3个月后又重写了一遍 这次时间100%
用有重复元素的全排列
M!的意思是M个元素总共的全排列。
由于a1有N1个元素,所以N1个元素的全排是重复的。
a2,an同上。
得出最后的结果M!/(N1!*N2!*...*Nn!)
class Solution { public: vector<int> v; vector<int> tmp; int cnt[30], ans, jc[8]; int cal() { int len = tmp.size(); int ret1 = 0, ret2 = 1; for(int i = 0; i < len; i++) { ret1 += tmp[i]; ret2 *= jc[tmp[i]]; } return jc[ret1] / ret2; } void dfs(int k, int x) { if(x > v.size()) return; if(x == v.size() && k != 0) return; if(k == 0) { ans += cal(); return; } for(int i = 0; i <= cnt[v[x]]; i++) { if(i != 0) tmp.push_back(i); dfs(k - i, x + 1); if(i != 0) tmp.pop_back(); } } int numTilePossibilities(string tiles) { jc[1] = 1; for(int i = 2; i <= 7; i++) jc[i] = jc[i - 1] * i; memset(cnt, 0, sizeof(cnt)); int len = tiles.length(); for(int i = 0; i < len; i++) { if(cnt[tiles[i] - 'A'] == 0) v.push_back(tiles[i] - 'A'); cnt[tiles[i] - 'A']++; } int ret = 0; for(int i = 1; i <= len - 1; i++) { ans = 0; dfs(i, 0); ret += ans; } int ret1 = len, ret2 = 1; for(int i = 0; i < v.size(); i++) { ret2 *= jc[cnt[v[i]]]; } return ret + jc[ret1] / ret2; } };