9. 1652.拆炸弹(简单,学习)
1652. 拆炸弹 - 力扣(LeetCode)
思想
为了获得正确的密码,你需要替换掉每一个数字。所有数字会 同时 被替换。
- 如果
k > 0
,将第i
个数字用 接下来k
个数字之和替换。 - 如果
k < 0
,将第i
个数字用 之前k
个数字之和替换。 - 如果
k == 0
,将第i
个数字用0
替换。
2.我的:
根据k的不同分三类情况讨论,先把 ∣ k ∣ |k| ∣k∣长度窗口的和求出来,然后根据k的正负向右或向左滑动窗口。
注意向左滑动时要+n再取余,i=(i-1+n)%n
3.学习
全部向右滑动,但是因为k的正负导致窗口在i的左侧或右侧,即**开始窗口位置不同,但保证窗口右移,从0开始遍历待赋值的元素i: - k>0,窗口为
[1,k+1)
- k<0,窗口为
[n-|k|,n) **通过记录一个变量right来维护
[right-k,right)`的窗口,但是保持right++**(而不是right=(right+1)%n,因为要始终保持right-k>0),但是sum更新的时候通过%n将`[right-k,right)`映射到对应范围内即可
代码
1.我的
c++:
class Solution {
public:vector<int> decrypt(vector<int>& code, int k) {int n = code.size();vector<int> res(n);if (k == 0) {for (int i = 0; i < n; ++i)res[i] = 0;} else if (k > 0) {long long sum = 0;for (int i = 0; i < k - 1; ++i)sum += (long long)code[i];int i = k - 1;int cnt = 0;for (;; i = (i + 1) % n) {sum += (long long)code[i];if ((i - k + n) % n == n - 1) {cnt++;if (cnt == 2)break;}res[(i - k + n) % n] = sum;sum -= (long long)code[(i - k + 1 + n) % n];}} else {long long sum = 0;int len = -1 * k;for (int i = n - 1; i > n - len; --i)sum += (long long)code[i];int i = n - len;int cnt = 0;for (;; i = (i - 1 + n) % n) {sum += (long long)code[i];if ((i + len + n) % n == 0) {cnt++;if (cnt == 2)break;}res[(i + len + n) % n] = sum;sum -= (long long)code[(i + len - 1 + n) % n];}}return res;}
};
2.学习:
c++:
class Solution {
public:vector<int> decrypt(vector<int>& code, int k) {int n = code.size();vector<int> res(n);int right = k > 0 ? k + 1 : n;k = abs(k);// 初始窗口和long long sum = 0;for (int i = right - k; i < right; ++i)sum += code[i];// 遍历赋值元素for (int i = 0; i < n; ++i) {res[i] = sum;sum -= code[(right - k + n) % n];sum += code[right % n];right++;}return res;}
};
10. 1176.健身计划评估(简单)
1176. 健身计划评估 - 力扣(LeetCode)
思想
1.为了更好地评估这份计划,对于卡路里表中的每一天,你都需要计算他 「这一天以及之后的连续几天」 (共 k
天)内消耗的总卡路里 T:
- 如果
T < lower
,那么这份计划相对糟糕,并失去 1 分; - 如果
T > upper
,那么这份计划相对优秀,并获得 1 分; - 否则,这份计划普普通通,分值不做变动。
代码
c++:
class Solution {
public:int dietPlanPerformance(vector<int>& calories, int k, int lower,int upper) {int n = calories.size();int res = 0;long long sum = 0;for (int i = 0; i < n; ++i) {sum += calories[i];if (i < k - 1)continue;if (sum > upper)res++;else if (sum < lower)res--;sum -= calories[i - k + 1];}return res;}
};
11. 1100.长度为K的无重复字符子串
1100. 长度为 K 的无重复字符子串 - 力扣(LeetCode)
思想
1.给你一个字符串 S
,找出所有长度为 K
且不含重复字符的子串,请你返回全部满足要求的子串的 数目。
2.利用map来储存字符个数,mp.size()==k
说明无重复字符
代码
c++:
class Solution {
public:int numKLenSubstrNoRepeats(string s, int k) {int res = 0;map<int, int> mp;for (int i = 0; i < s.size(); ++i) {mp[s[i]]++;if (i < k - 1)continue;if (mp.size() == k)res++;mp[s[i - k + 1]]--;if (mp[s[i - k + 1]] == 0)mp.erase(s[i - k + 1]);}return res;}
};
1.mp.size()
统计key的数量
2.mp.erase(key)
,删除键值对