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