You have a set of tiles
, where each tile has one letter tiles[i]
printed on it. Return the number of possible non-empty sequences of letters you can make.
Example 1:
Input: "AAB"
Output: 8
Explanation: The possible sequences are "A", "B", "AA", "AB", "BA", "AAB", "ABA", "BAA".
Example 2:
Input: "AAABBC"
Output: 188
Note:
1 <= tiles.length <= 7
tiles
consists of uppercase English letters.
思路一:根据给定字符串,生成所有的序列方式可以直接利用回溯法生成,但是由于有些字符重复,所以会有重复的子序列生成,因此我们可以用set处理。
1 class Solution { 2 private: 3 void combination(const string &tiles, int len, vector<bool> &visited, string &temp, set<string> &st) { 4 if (temp.length() > 0 && temp.length() <= len && st.find(temp) == st.end()) { 5 st.insert(temp); 6 } 7 if (temp.length() > len) 8 return; 9 for (int i = 0; i < len; ++i) { 10 if (!visited[i]) { 11 visited[i] = true; 12 temp.push_back(tiles[i]); 13 combination(tiles, len, visited, temp, st); 14 visited[i] = false; 15 temp.pop_back(); 16 } 17 } 18 } 19 public: 20 int numTilePossibilities(string tiles) { 21 set<string> st; 22 int length = tiles.length(); 23 string temp = ""; 24 vector<bool> visited(length, false); 25 combination(tiles, length, visited, temp, st); 26 return st.size(); 27 } 28 };
思路二:
class Solution { private: int dfs(vector<int> &cnt) { int num = 0; for (int i = 0; i < 26; ++i) { if (cnt[i] == 0) continue; num++; cnt[i]--; num += dfs(cnt); cnt[i]++; } return num; } public: int numTilePossibilities(string tiles) { vector<int> cnt(26, 0); for (auto c: tiles) { cnt[c - 'A']++; } return dfs(cnt); } };
这种做法保证了在子序列字符串的某一位字符选择上不会重复选择