Leetcode 第 134 场双周赛题解
Leetcode 第 134 场双周赛题解
题目1:3206. 交替组 I
思路
向数组 colors 后面插入 colors[0] 和 colors[1],模拟成一个环的效果。
代码
/*
* @lc app=leetcode.cn id=3206 lang=cpp
*
* [3206] 交替组 I
*/
// @lc code=start
class Solution
{
public:
int numberOfAlternatingGroups(vector<int> &colors)
{
int n = colors.size();
colors.push_back(colors[0]);
colors.push_back(colors[1]);
int cnt = 0;
for (int i = 0; i < n; i++)
{
if (colors[i] != colors[i + 1] && colors[i + 1] != colors[i + 2])
cnt++;
}
return cnt;
}
};
// @lc code=end
复杂度分析
时间复杂度:O(n),其中 n 是数组 colors 的长度。
空间复杂度:O(1)。
题目2:3207. 与敌人战斗后的最大分数
思路
设 enemyEnergies 中的最小值为 minEnergy,元素和为 sum。
如果 currentEnergy < minEnergy,那么操作一无法执行,无法得到任何分数,所以也无法执行操作二,返回 0。
否则,操作顺序如下:
- 对 minEnergy 执行操作一,得到 1 分。
- 对除了 minEnergy 以外的敌人执行操作二,得到 sum − minEnergy 的能量。
- 对 minEnergy 执行操作一,直到能量不足。
- 也可以理解为,先得到 sum − minEnergy 的能量,再不断对 minEnergy 执行操作一,所以得分为 (currentEnergy + sum - minEnergy) / minEnergy。
代码
/*
* @lc app=leetcode.cn id=3207 lang=cpp
*
* [3207] 与敌人战斗后的最大分数
*/
// @lc code=start
class Solution
{
public:
long long maximumPoints(vector<int> &enemyEnergies, int currentEnergy)
{
int minEnergy = *min_element(enemyEnergies.begin(), enemyEnergies.end());
if (currentEnergy < minEnergy)
return 0;
long long sum = accumulate(enemyEnergies.begin(), enemyEnergies.end(), 0LL);
return (currentEnergy + sum - minEnergy) / minEnergy;
}
};
// @lc code=end
复杂度分析
时间复杂度:O(n),其中 n 是数组 enemyEnergies 的长度。
空间复杂度:O(1)。
题目3:3208. 交替组 II
思路
把数组复制一份拼接起来,和 3101 题一样,遍历数组的同时,维护以 i 为右端点的交替子数组的长度 cnt。
如果 i ≥ n 且 cnt ≥ k,那么 i 就是一个长为 k 的交替子数组的右端点,答案加一。注意这里要判断 i ≥ n,从而避免重复统计。
代码实现时,不需要复制数组,而是用 i mod n 的方式取到对应的值。
代码
/*
* @lc app=leetcode.cn id=3208 lang=cpp
*
* [3208] 交替组 II
*/
// @lc code=start
class Solution
{
public:
int numberOfAlternatingGroups(vector<int> &colors, int k)
{
int n = colors.size();
int ans = 0, cnt = 0;
for (int i = 0; i < n * 2; i++)
{
if (i > 0 && colors[i % n] == colors[(i - 1) % n])
{
cnt = 0;
}
cnt++;
ans += i >= n && cnt >= k;
}
return ans;
}
};
// @lc code=end
复杂度分析
时间复杂度:O(n),其中 n 是数组 colors 的长度。
空间复杂度:O(1)。
题目4:3209. 子数组按位与值为 K 的数目
思路
题解:三种基于 logTrick 的方法:二分 / 三指针 / 维护个数(Python/Java/C++/Go)。
代码
/*
* @lc app=leetcode.cn id=3209 lang=cpp
*
* [3209] 子数组按位与值为 K 的数目
*/
// @lc code=start
class Solution
{
public:
long long countSubarrays(vector<int> &nums, int k)
{
long long ans = 0;
for (int i = 0; i < nums.size(); i++)
{
int x = nums[i];
for (int j = i - 1; j >= 0 && (nums[j] & x) != nums[j]; j--)
{
nums[j] &= x;
}
ans += upper_bound(nums.begin(), nums.begin() + i + 1, k) -
lower_bound(nums.begin(), nums.begin() + i + 1, k);
}
return ans;
}
};
// @lc code=end