开始积累自己的题量了,不得不说LeetCode这种专门针对一类题目的每日一题真的太适合萌新了,这个月做完希望滑动窗口的题目能够自信手撕。
2/1 :
思路:我们可以分别算出爱丽丝和鲍勃的糖果棒大小的总和,这样对于鲍勃/爱丽丝的每一根糖果,需要爱丽丝/鲍勃交换的那根的大小就是固定的。然后就变成寻找数字的问题了。采用哈希是查找最快的方法。
class Solution {
public:
vector<int> fairCandySwap(vector<int>& A, vector<int>& B) {
int sumA = accumulate(A.begin(), A.end(), 0);
int sumB = accumulate(B.begin(), B.end(), 0);
int tmp = (sumA - sumB) / 2;
unordered_set<int> s(A.begin(), A.end());
vector<int> ans;
for (int y : B) {
int x = y + tmp;
if (s.find(x) != s.end()) {
ans.push_back(x);
ans.push_back(y);
break;
}
}
return ans;
}
};
时间复杂度O(n)
空间复杂度O(1)
2/2见链接题解
2/3见链接题解
2/4:
思路:对于每个元素:存储小标到目前为止的元素和,用于后序快速算出滑动窗口内的元素和。
后序只要固定窗口大小往右滑动,每次更新最大值即可。
class Solution {
public:
double findMaxAverage(vector<int>& nums, int k) {
int left = 0, right = k - 1;
for(int i = 0; i < nums.size() - 1; i++) {
nums[i + 1] += nums[i];
}
double ans = nums[k - 1] * 1.0 / k;
for(int i = k ; i < nums.size(); i++) {
double tmp = (nums[i] - nums[i - k]) * 1.0 / k;
ans = max(tmp, ans);
}
return ans;
}
};
时间复杂度O(n)
空间复杂度O(1)
2/5:
思路:和 替换后的最长重复子字符串 、 最长不含重复字符的子字符串 差不多,右边界不断扩大,直到发现不满足的时候左边界再改变,右边界超过数组的时候停止,非常经典的滑动窗口模板。
class Solution {
public:
int equalSubstring(string s, string t, int maxCost) {
if(s == t) return s.size();
int len = s.size();
int left = 0, right = 0,cost = 0;
while(right < len) {
cost += abs(s[right] - t[right]);
if(cost > maxCost) {
cost -= abs(s[left] - t[left]);
left++;
}
right++;
}
return right - left;
}
};
时间复杂度O(n)
空间复杂度O(1)