美文网首页
Backtracking 两道题 (Leetcode 464,

Backtracking 两道题 (Leetcode 464,

作者: stepsma | 来源:发表于2018-03-13 12:57 被阅读0次

    把两道比较难的Backtracking的类似题放到一起,总结一下格式。

    两道题的具体讲解参考youtube:
    https://www.youtube.com/watch?v=md3qQ-5B0aU&t=1199s

    两道题都是要建立状态数组,并在recursion时遍历状态数组。注意backtracking时把状态设回来。

    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;
        }
    };
    

    相关文章

      网友评论

          本文标题:Backtracking 两道题 (Leetcode 464,

          本文链接:https://www.haomeiwen.com/subject/hmczfftx.html