Backtracking 兩道題 (Leetcode 464, Leetcode 698)

把兩道比較難的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;
    }
};
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容