Leetcode 周賽 218 題解

5617. 設計 Goal 解析器html

按題意模擬,基礎題。c++

class Solution {
public:
    string str;
    string interpret(string command) {
        for(int i = 0; i < command.size();i++){
            if(command[i] == 'G') str += 'G';
            else if(i != command.size() - 1 && command[i] == '(' && command[i + 1] == ')') str += 'o';
            else if(command[i] == 'a') str += "al";
        }
        return str;
    }
};

5618. K 和數對的最大數目數組

經典技巧題,比較好的解法是排序以後雙指針求解。固然能夠用map投機就很好寫了。設計

雙指針求解指針

class Solution {
public:
  int maxOperations(vector<int>& nums, int k) {
    int N =  nums.size();
    sort(nums.begin(), nums.end());
    int ans = 0;
    int l = 0, r = nums.size() - 1;
    while (l<r) {
      int s = nums[l]+nums[r];
      if (s == k) l++, r--, ans++;
      else if (s < k) l++;
      else r--;
    }
    return ans;
  }
};

mapcode

class Solution {
public:
    int maxOperations(vector<int>& nums, int k) {
        map<int, int> mp;
        int ans = 0;
        for(int x: nums) {
            if(mp[k - x] > 0) {
                mp[k - x] -= 1;
                ++ ans;
            }else mp[x] += 1;
        }
        return ans;
    }
};

5620. 鏈接連續二進制數字htm

從後往前求每一個數的貢獻值便可blog

class Solution {
public:
    int concatenatedBinary(int n) {
        long long mod = pow(10,9) + 7;
        long long ans = 0, base = 1;
        for(int i = n; i >= 1; --i) {
            n = i;
            while(n > 0) {
                long long x = n & 1;
                n >>= 1;
                ans = (ans + base * x) % mod;
                base = base * 2 % mod;
            }
        }
        return (int)ans;
    }
};

5619. 最小不兼容性排序

數組和權值範圍最大隻有16,由於要把數組分紅k個子集,那麼每一個子集大小就是n/k。get

第一種方法:

經過set判斷子集中的重複元素,搜索+剪枝便可,具體見代碼

class Solution {
public:
    int N;//總個數
    int K;//子集個數
    int M;//每一個子集中的元素個數
    int ans;//求解值
    void dfs(vector<int>& nums,int index,vector<set<int>> &vSet,int have){
    	/*
    	index 表示當前數組取到的值
    	vSet 表示子集
    	*/
        if(index>=N){//當取到最後一位時終止,判斷
            ans=min(ans,have);
            return;
        }
        
        for(int i=0;i<K;i++){
            if(vSet[i].empty()){// 子集個數爲空
                vSet[i].insert(nums[index]);
                dfs(nums,index+1,vSet,have);//取下個元素
                vSet[i].erase(nums[index]);
                break;//當有出現大於K個相同數時,不可能
            }
            if(vSet[i].size()<M&&vSet[i].find(nums[index])==vSet[i].end()){//當前子集個數未滿且當前元素子集中未存在
                if(have + nums[index] - *vSet[i].rbegin()>=ans){
                	//剪枝 當前數已經比最小值大
                    continue;
                }
                int nhave = have + nums[index] - *vSet[i].rbegin();
                vSet[i].insert(nums[index]);
                dfs(nums,index+1,vSet,nhave);

                vSet[i].erase(nums[index]);                
            }
        }
        
    }
    int minimumIncompatibility(vector<int>& nums, int k) {
        N=nums.size();
        sort(nums.begin(),nums.end());
        ans = INT_MAX;
        K=k;
        M=N/K;
        vector<set<int>> vSet(k);
        dfs(nums,0,vSet,0);
        if(ans == INT_MAX){
            return -1;
        }
        return ans;
    }
};

第二種方法:

首先二進制枚舉求出全部合法的子集,這樣的子集個數不會太多。

能夠經過二進制枚舉求出因此合法的子集,同狀態壓縮。

而後寫一個搜索+剪枝便可。

class Solution {
public:
    int ans, n, sz;
    vector<pii> vs;
    void dfs(int c, int cnt, int sta, int res, int k) {
        if(cnt == k) {
            ans = min(ans, res);
            return ;
        }
        if(res >= ans) return ;
        for(int i = c; i < sz; ++i) {
            if((sta & vs[i].se) == 0) dfs(i + 1, cnt + 1, sta | vs[i].se, res + vs[i].fi, k);
        }
    }
    int minimumIncompatibility(vector<int>& nums, int k) {
        vector<int> cnt(20, 0);
        int flag = 1;
        ans = INF;
        for(int x: nums) {
            ++ cnt[x];
            if(cnt[x] > k) flag = 0;
        }
        if(flag == 0) return -1;
        n = nums.size();
        int sta = 1 << n;
        sort(all(nums));
        for(int i = 1; i < sta; ++i) {
            int cnt = 0, Mx = 0, Mn = 100, las = -1;
            for(int j = 0; j < n; ++j) {
                if(i & (1 << j)) {
                    ++ cnt;
                    Mx = max(Mx, nums[j]);
                    Mn = min(Mn, nums[j]);
                    if(nums[j] == las) cnt = -100;
                    las = nums[j];
                }
            }
            if(cnt * k == n) {
                vs.emplace_back(make_pair(Mx - Mn, i));
            }
        }
        sort(all(vs));
        sz = vs.size();
        dfs(0, 0, 0, 0, k);
        vs.clear();
        return ans;
    }
};
相關文章
相關標籤/搜索