目录
一,3206. 交替组 I
直接暴力,代码如下:
class Solution {
public int numberOfAlternatingGroups(int[] nums) {
int ans = 0;
int n = nums.length;
for(int i=0; i<n; i++){
if(nums[i%n]!=nums[(i+1)%n] && nums[i%n]==nums[(i+2)%n]){
ans++;
}
}
return ans;
}
}
二,3207. 与敌人战斗后的最大分数
本题就是一道阅读理解题,可以从游戏的角度去理解:
- currentEnergy就是当前你所拥有的体力,enemyEnergies数组就是游戏中的各种副本(每个副本需要的体力可以不同),但是在本题中刷一个副本只能得到一分
- 操作一就是使用体力去刷副本,我们每刷一个副本就可以获得一分,每个副本可以无限刷
- 操作二就是选择永远不刷这个副本,从而获得对应副本刷一次所需的体力,注意:前提是必须先获得一分
综上所述,可以发现只有当我们将所有的体力去刷所需体力最小的副本,才能获得最多的分数,但是需要特判一种情况——就是我们连一分也得不到,即 currtEnergy < min(nemyEnergies),直接返回 0.
代码如下:
class Solution {
public long maximumPoints(int[] enemyEnergies, int currentEnergy) {
long mn = enemyEnergies[0], s = 0;
for(int x : enemyEnergies){
mn = Math.min(mn, x);
s += x;
}
if(currentEnergy < mn) return 0;
return (currentEnergy+s-mn)/mn;
}
}
三,3208. 交替组 II
本题先解决如何判断它是连续k个相邻元素不同的子数组,可以使用一个变量cnt来统计出现几个相邻不同的数,如果cnt >= k(即满足条件),答案++。
接下来就是如何解决它是一个环的问题,我们可以在colors数组后面再copy一下它自己,比如[1,0,1] ——》[1,0,1,1,0,1],这样就将环转换成了一个数组,但是这里有一个要注意的点是,我们需要在 i >= n 的时候再统计答案,否则会重复计算。
代码如下:
class Solution {
public int numberOfAlternatingGroups(int[] colors, int k) {
int n = colors.length;
int cnt = 0, ans = 0;
for(int i=0; i<2*n; i++){
if(i>0 && colors[i%n]==colors[(i-1)%n]){
cnt = 0;
}
cnt++;
if(i>=n && cnt >= k)
ans++;
}
return ans;
}
}
四,3209. 子数组按位与值为 K 的数目
本题其实是400周赛的T4,只不过这里问的是有多少子数组,可以使用暴力的思路来写,就是两层for循环遍历,但是可以使用一个 if 条件使其复杂度降低为O(nlongU),U=max(nums),这里就不细讲了,不会的看400周赛的那篇题解。
剩下的就是如何计算子数组数量了,因为 &运算有个性质,它 & 的数越多,它的值只能变的越小或不变,具有单调性,所以可以使用两次二分来查找子数组的右端点的范围 [ l,r),ans += r - l,根据其单调性,我们也可以使用滑动窗口的形式来查找子数组右端点的范围。
代码如下:
class Solution {
public long countSubarrays(int[] nums, int k) {
long ans = 0;
int l = 0, r = 0, n = nums.length;
for(int i=0; i<n; i++){
int x = nums[i];
for(int j=i-1; j>=0; j--){
if((nums[j]&x) == nums[j])
break;
nums[j] &= x;
}
while(l <= i && nums[l] < k)
l++;
while(r <= i && nums[r] <= k)
r++;
ans += r - l;
}
return ans;
}
}
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » Leetcode - 133双周赛
发表评论 取消回复