LeetCode -- 第 359 场周赛(区间问题+动态规划、计数+双指针)
本题我们只需要将所有首字母取出来,并与s比较即可。
class Solution { public: bool isAcronym(vector<string>& words, string s) { string res; for(auto &it: words) { res += it[0]; } return res == s; } };
经典哈希表应用,我们要找n个不同的数字,且任意两个数组和不能为k。将i加入答案中同时将k - i加入到哈希表中即可。
class Solution { public: int minimumSum(int n, int k) { vector<int> cnts; unordered_map<int, int> mp; for(int i = 1; ; i ++ ) { if(cnts.size() == n) break; if(mp[i] == 0) { cnts.push_back(i); mp[k - i] = 1; } } int res = 0; for(auto it: cnts) { res += it; } return res; } };
区间问题常见解法有动态规划,贪心, 双指针。本题采用动态规划来解
f[i]表示只从前0 - i中选,所获得的最大价值。
若不选第i个点 f[i] = f[i - 1];若选di第i个点,则第i个点一定是某个区间的右端点,向前遍历其左端点j, f[i] = max(f[i], f[j - 1] + w)
class Solution { public: int maximizeTheProfit(int n, vector<vector<int>>& offers) { int m = offers.size(); vector<int> f(n + 1); vector<vector<int>> g(n); for(int i = 0; i < m; i ++ ) { g[offers[i][1]].push_back(i); //右端点处记录该段所在位置 } for(int i = 1; i <= n; i ++ ) { f[i] = f[i - 1]; for(int j: g[i - 1]) { f[i] = max(f[i], f[offers[j][0]] + offers[j][2]); //之前的左端点 + 当前区间价值 } } return f[n]; } };
可以有计数 + 二分、计数+双指针两种解法
计数用来快速查找出两个相邻元素中其他元素数量
方法一、计数+二分
二分枚举最长长度,
class Solution { public: int longestEqualSubarray(vector<int>& nums, int k) { int n = nums.size(), l = 0, r = n + 1; unordered_map<int, vector<int>> mp; for(int i = 0; i < n; i ++ ) { mp[nums[i]].push_back(i); } auto check = [&](int len) -> bool { for(auto &[_, vec]: mp) { for(int i = 0; i + len - 1 < vec.size(); i ++ ) { if(vec[i + len - 1] - vec[i] + 1 - len <= k) return true; } } return false; }; while(l + 1 < r) { int mid = l + r >> 1; if(check(mid)) l = mid; else r = mid; } return l; } };
方法二:计数+双指针
class Solution { public: int longestEqualSubarray(vector<int>& nums, int k) { int n = nums.size(); vector<vector<int>> p(n + 1); for(int i = 0; i < n; i ++ ) { p[nums[i]].push_back(i); } int res = 0; for(int u = 1; u <= n; u ++ ) { auto &q = p[u]; for(int i = 0, j = 0; i < q.size(); i ++ ) { while((q[i] - q[j]) - (i - j) > k) j ++ ; //q[i] - q[j] + 1 两个相同元素中间元素个数 i - j + 1两个相同元素中间和该元素相同的元素个数 res = max(res, i - j + 1); } } return res; } };