问题:
将给定的字符串s,最多能够分割成多少个互不重复的字符串?
Example 1: Input: s = "ababccc" Output: 5 Explanation: One way to split maximally is ['a', 'b', 'ab', 'c', 'cc']. Splitting like ['a', 'b', 'a', 'b', 'c', 'cc'] is not valid as you have 'a' and 'b' multiple times. Example 2: Input: s = "aba" Output: 2 Explanation: One way to split maximally is ['a', 'ba']. Example 3: Input: s = "aa" Output: 1 Explanation: It is impossible to split the string any further. Constraints: 1 <= s.length <= 16 s contains only lower case English letters.
解法:Backtracking(回溯算法)
状态:到当前位置pos位置,切割的结果path。
选择:从当前位置pos开始,长度为1~s结束的子串中,不与path中的字符串重复的。
递归退出条件:pos==s.length,选择最大的path.size
⚠️ 注意:原本想要剪枝,选取最大res,则是只要找到res,就是最多分割的情况。
但是还存在,
前面分割字符串较长,可使后面字符串不重复,最终得到res更大的情况。
如:"wwwzfvedwfvhsww"
若前面分割了www,后面可最终得到res=11
但如果分割了w,和ww,那么最终res=10。
代码参考:
1 class Solution { 2 public: 3 void backtrack(int& res, int pos, string& s, unordered_set<string>& path) { 4 if(pos==s.length()) { 5 res = max(res, (int)path.size()); 6 return; 7 } 8 for(int i=pos+1; i<=s.length(); i++) { 9 string cur = s.substr(pos, i-pos); 10 if(path.count(cur)==0) { 11 path.insert(cur); 12 backtrack(res, i, s, path); 13 path.erase(cur); 14 } 15 } 16 return; 17 } 18 int maxUniqueSplit(string s) { 19 int res = 0; 20 unordered_set<string> path; 21 backtrack(res, 0, s, path); 22 return res; 23 } 24 };