LeetCode 周赛200
5475. 统计好三元组
难度: Easy
题目描述:
链接:5475. 统计好三元组
解题思路:
暴力三重循环模拟
class Solution {
public:
int countGoodTriplets(vector<int>& arr, int a, int b, int c) {
int ans = 0;
for(int i = 0; i < arr.size(); i++){
for(int j = i + 1; j < arr.size(); j++){
for(int k = j + 1;k < arr.size(); k++){
if(abs(arr[i] - arr[j]) <= a && abs(arr[j] - arr[k]) <= b && abs(arr[i] - arr[k]) <= c){
ans++;
}
}
}
}
return ans;
}
};
5476. 找出数组游戏的赢家
难度:Medium
题目描述:
解题思路:
首先模拟的过程中,不需要对将前两个中较小的结点移到末尾。
采用两个下标指针,nowWinner指向当前的最大值,i指向当前挑战的结点。
- 当当前最大的结点nowWinner > i ,则计数器nowCount+1
- 否则,挑战结点i变为nowWinner,计数器nowCount 置 1
- 计数器达到k时,返回结果
class Solution {
public:
int getWinner(vector<int>& arr, int k) {
int nowWinner = 0;
int nowCount = 0;
for(int i = 1; i < arr.size(); i++){
if(arr[nowWinner] < arr[i]){
nowWinner = i;
nowCount = 1;
}else{
nowCount++;
}
if(nowCount >= k){
break;
}
}
return arr[nowWinner];
}
};
5478. 最大得分
难度:Hard
题目描述:
题目链接:
5478. 最大得分
解题思路:
假设有K个值相同的结点,则把整2个数组分成了k+1段,
- 每次统计两个数组各段中的sum1,sum2,
- 然后在相同的节点处进行统计,ans += max(sum1, sum2) + nums1[i]
- 注意要处理较长的数组,剩下的部分,额外加到ans中,ans += max(sum1, sum2)
class Solution {
public:
int maxSum(vector<int>& nums1, vector<int>& nums2) {
int i = 0,j = 0;
long sum1 = 0, sum2 = 0;
long ans = 0;
while(i < nums1.size() && j < nums2.size()){
if(nums1[i] == nums2[j]){ // 走到公共结点时统计结点的最大值
ans += (max(sum1, sum2) + nums1[i]);
sum1 = 0;
sum2 = 0;
i++;
j++;
}else if(nums1[i] < nums2[j]){
sum1 += nums1[i];
i++;
}else{
sum2 += nums2[j];
j++;
}
}
// 处理长度较长的数组的剩余部分
while(i < nums1.size()){
sum1 += nums1[i];
i++;
}
while(j < nums2.size()){
sum2 += nums2[j];
j++;
}
ans += max(sum1, sum2);
return ans % ((int)pow(10, 9) + 7);
}
};
5477. 排布二进制网格的最少交换次数
难度: Medium
题目描述:
解题思路:
采用贪心策略。满足条件的行后缀0的个数必须大于n-i-1个。
- 遍历每一行,统计每一行的后缀0的个数,存入count0的数组中
- 从第一行向下判断每一行的count0是否符合条件,符合条件则判断下一行
- 如果不符合,向下寻找第一个符合条件的行j,然后一次交换j和j-1,直到i处
- 如果找不到符合的行,则返回-1
class Solution {
public:
int minSwaps(vector<vector<int>>& grid) {
int n = grid.size();
vector<int> count0; // 用来统计每一行后缀0的个数
// 每一行从后向前,统计后缀中0的个数
for(int i = 0; i < n; i++){
int temp = 0;
for(int j = n-1; j >= 0; j--){
if(grid[i][j] == 0){
temp++;
}else{
break;
}
}
count0.push_back(temp);
}
int count_change = 0; // 记录交换的次数
// 一次判断每一行是否满足条件
// 不满足条件的行一次向上交换
for(int i = 0; i < n; i++){
if(count0[i] >= n - i - 1){ // 当前行符合后缀0的个数,直接判断下一行
continue;
}else{
int j = i;
for(; j < n; j++){ // 寻找下面的行中,满足条件的下标j
if(count0[j] >= n - i - 1){
break;
}
}
if(j == n){ // 没有符合条件的行
return -1;
}else{
for(; j > i; j--){ // 依次向上交换
swap(count0[j-1], count0[j]);
count_change++;
}
}
}
}
return count_change;
}
};