把兩道比較難的Backtracking的類似題放到一起,總結(jié)一下格式。
兩道題的具體講解參考youtube:
https://www.youtube.com/watch?v=md3qQ-5B0aU&t=1199s
兩道題都是要建立狀態(tài)數(shù)組,并在recursion時(shí)遍歷狀態(tài)數(shù)組。注意backtracking時(shí)把狀態(tài)設(shè)回來。
Can I Win (464)
class Solution {
public:
bool canIWin(int maxChoosableInteger, int desiredTotal) {
int maxSum = (1 + maxChoosableInteger) * maxChoosableInteger / 2;
if(maxSum < desiredTotal) return false;
vector<int> subset(maxChoosableInteger+1, 0);
return canwin(subset, desiredTotal);
}
bool canwin(vector<int> &subset, int total){
string cur = convertString(subset);
if(mp.count(cur)) return mp[cur];
for(int i=1; i<subset.size(); i++){
if(subset[i] == 0){
subset[i] = 1;
if(total - i <= 0 || !canwin(subset, total-i)){
mp[cur] = true;
subset[i] = 0;
return true;
}
subset[i] = 0;
}
}
mp[cur] = false;
return false;
}
string convertString(vector<int> &subset){
string s = "";
for(int it : subset){
s += '0' + it;
}
return s;
}
private:
unordered_map<string, bool> mp;
};
Partition to K Equal Sum Subsets (698)
class Solution {
public:
bool canPartitionKSubsets(vector<int>& nums, int k) {
if(nums.empty()) return false;
int sum = accumulate(begin(nums), end(nums), 0, plus<int>());
if(sum % k != 0) return false;
int target = sum / k;
// cout << target << endl;
sort(nums.begin(), nums.end());
int beginIndex = nums.size()-1;
if(nums[beginIndex] > target) return false;
while(beginIndex >= 0 && nums[beginIndex] == target){
beginIndex--;
k--;
}
vector<int> subSet(k, 0);
return partition(subSet, nums, beginIndex, target);
}
bool partition(vector<int> &subset, vector<int>& nums, int index, int target){
if(index < 0){
return true;
}
int selected = nums[index];
for(int i=0; i<subset.size(); i++){
if(subset[i] + selected <= target){
subset[i] += selected;
if(partition(subset, nums, index-1, target)){
return true;
}
subset[i] -= selected;
}
}
return false;
}
};