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)
,删除键值对