zoukankan      html  css  js  c++  java
  • Leetcode 周赛 218 题解

    5617. 设计 Goal 解析器

    按题意模拟,基础题。

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

    map

    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. 连接连续二进制数字

    从后往前求每个数的贡献值即可

    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。

    第一种方法:

    通过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;
        }
    };
    
  • 相关阅读:
    delphi string.split 按照任意字符串分割语句
    学习 TTreeView [16]
    学习 TTreeView [15]
    delphi TClientDatset资料
    delphi7 clientdataset 详解
    为TMenuItem增加指针Data属性
    构建一个用于产品介绍的WEB应用
    图片延迟加载技术-Lazyload的应用
    你想不到的压缩方法:将javascript文件压缩成PNG图像存储
    如何更快速加载你的JS页面
  • 原文地址:https://www.cnblogs.com/DWVictor/p/14099736.html
Copyright © 2011-2022 走看看