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