代码随想录算法训练营第二十二天| 39. 组合总和 40.组合总和II 131.分割回文串
39. 组合总和
思路:
虽然可以是重复的,但是考虑到组合没有顺序这一说,所以还是要保留startIndex,
sum不要再遍历一遍,再相加,应该跟随path,一起相加
代码:
1 void combinationSum_trackBack(vector<int>& candidates, int target, 2 int sum_,int startIndex, vector<int>& path, vector<vector<int>>& result) 3 { 4 if (sum_ > target) 5 return; 6 if (sum_ == target) 7 { 8 result.push_back(path); 9 return; 10 } 11 12 for (int i = startIndex; i < candidates.size(); i++) 13 { 14 sum_ += candidates[i]; 15 path.push_back(candidates[i]); 16 combinationSum_trackBack(candidates, target, sum_,i, path, result); 17 path.pop_back(); 18 if (sum_ > target) 19 { 20 return; 21 } 22 sum_ -= candidates[i]; 23 } 24 } 25 26 vector<vector<int>> combinationSum(vector<int>& candidates, int target) { 27 vector<vector<int>>result; 28 if (candidates.size() == 0) return result; 29 30 set<map<int, int>> check_dup; 31 vector<int>path; 32 sort(candidates.begin(), candidates.end()); 33 combinationSum_trackBack(candidates, target,0,0, path, result); 34 return result; 35 }
40.组合总和II
思路:
难点是给的数组里面有重复的,所以需要对当前层进行删减
代码:
1 void combinationSum2_trackBack(vector<int>& candidates, int target, 2 int sum, int startIndex, vector<int>&path, vector<vector<int>>& result) 3 { 4 if (sum > target) 5 return; 6 if (sum == target) 7 { 8 result.push_back(path); 9 return; 10 } 11 12 set<int> selected; 13 for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++) 14 { 15 //需要在相同层里面对他们去重 16 if (selected.find(candidates[i]) != selected.end()) 17 continue; 18 19 selected.insert(candidates[i]); 20 sum += candidates[i]; 21 path.push_back(candidates[i]); 22 combinationSum2_trackBack(candidates, target, sum, i + 1, path, result); 23 sum -= candidates[i]; 24 path.pop_back(); 25 } 26 27 } 28 vector<vector<int>> combinationSum2(vector<int>& candidates, int target) { 29 vector<vector<int>> result; 30 if (candidates.size() == 0)return result; 31 32 vector<int>path; 33 sort(candidates.begin(), candidates.end()); 34 combinationSum2_trackBack(candidates, target, 0, 0, path, result); 35 36 return result; 37 }
131.分割回文串
思路:
1,注意这是分割,而不是对多个char进行分组,所以需要想到用分割的方法
2,其中注意到怎么跟个 [start,i],这样分割
3,怎么快速直到这个是不是回文串
4,判断终止条件,一般我会认为他是回文串就终止,但是可能后面还会添加新的,也就是说vector<string>,里面不可能只有一个回文串
开始的时候认为只要里面的单词,全部组合成string s就可以了,仔细想了想,可以和区间的start来比较
如果start是最后了,那么也就没有必要再去搞
代码:
1 bool isPartition(string &s, int start, int end) 2 { 3 string ori(s.begin() + start, s.begin() + end+1); 4 string rever = ori; 5 reverse(rever.begin(), rever.end()); 6 return rever == ori; 7 } 8 void partition_trackBack(string s, int startIndex, vector<string>&path,vector<vector<string>>&result) 9 { 10 //证明已经遍历完成 ————很重要 11 if (startIndex >= s.size()) 12 { 13 result.push_back(path); 14 return; 15 } 16 17 for (int i = startIndex; i < s.size(); i++) 18 { 19 if (isPartition(s, startIndex, i)) 20 { 21 path.emplace_back(s.begin() + startIndex, s.begin() + i + 1); 22 partition_trackBack(s, i + 1, path, result); 23 path.pop_back(); 24 } 25 else 26 { 27 continue; 28 } 29 } 30 } 31 vector<vector<string>> partition(string s) { 32 vector<vector<string>> result; 33 if (s.size() == 0) return result; 34 vector<string> path; 35 36 partition_trackBack(s, 0, path, result); 37 return result; 38 }