第 321 场周赛
Date: 2022-11-27
A 找出中枢整数
暴力 \(O(n^2)\) 或者等差数列求和 \(O(n)\)
复杂度分析
- 时间复杂度:\(O(n)\) or \(O(n^2)\)
- 空间复杂度:\(O(1)\)
B 追加字符以获得子序列
双指针
复杂度分析
- 时间复杂度:\(O(\max(n, m))\)
- 空间复杂度:\(O(1)\)
C 从链表中移除节点
单调栈
复杂度分析
- 时间复杂度:\(O(n)\)
- 空间复杂度:\(O(n)\)
D 统计中位数为 K 的子数组
中位数为 \(k\) 的子数组(长度为 \(n\))中,按照长度奇偶可以分为两种情况:
- 偶数,小于 \(k\) 的个数等于 \(n/2 - 1\),大于 \(k\) 的个数等于 \(n/2\)
- 奇数,小于 \(k\) 的个数等于 \(\lfloor n/2\rfloor\),大于 \(k\) 的个数等于 \(\lfloor n/2 \rfloor\)。
可以发现,不管奇偶,大于 \(k\) 的个数总是与小于 \(k\) 的个数相等或大于 \(1\)。
因此,找到 \(k\) 的位置 \(pos\),遍历 \(pos\) 之前的每个位置 \(i\),递推求解 \(i\sim pos\) 之间「大于 \(k\) 的数字个数减去小于 \(k\) 的数字个数」。而对于 \(pos\) 之后的位置也做同样计算,统计前后该个数加起来等于 0 或等于 1 的情况数即可。
class Solution {
public:
int countSubarrays(vector<int>& nums, int k) {
int pos = find(nums.begin(), nums.end(), k) - nums.begin();
unordered_map<int, int> mp;
int cur = 0;
for (int i = pos; i >= 0; i--) {
if (nums[i] < k) cur--;
else if(nums[i] > k) cur++;
mp[cur]++;
}
cur = 0;
int res = 0;
for (int i = pos; i < nums.size(); i++) {
if (nums[i] < k) cur--;
else if (nums[i] > k) cur++;
res += mp[-cur] + mp[-cur + 1];
}
return res;
}
};
复杂度分析
- 时间复杂度:\(O(n)\)
- 空间复杂度:\(O(n)\)
本文访问 次