持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第28天,点击查看活动详情
前言
小白算法比较菜,希望能激励我每日更新,从leetcode第一题开始,2022年目标300题,记录从0到1的全过程!!
力扣第 316 场周赛-力扣
力扣第 316 场周赛-力扣
这次第三题就是hard,想破头也没想出来。直接掉大分啊!当时看第二题太复杂就先去看第三题了,早知道先把第二题做了,说不定还能不掉分。。
第315双周赛的排名
第314双周赛的排名
第313周赛的排名
2447. 最大公因数等于 K 的子数组数目
给你一个整数数组 nums 和一个整数 k ,请你统计并返回 nums 的子数组中元素的最大公因数等于 k 的子数组数目。
子数组 是数组中一个连续的非空序列。
数组的最大公因数 是能整除数组中所有元素的最大整数。
示例 1
- 输入:nums = [9,3,1,2,6,3], k = 3
- 输出:4
- 解释:nums 的子数组中,以 3 作为最大公因数的子数组如下:
- [9,3,1,2,6,3]
- [9,3,1,2,6,3]
- [9,3,1,2,6,3]
- [9,3,1,2,6,3]
示例 2
- 输入: nums = [4], k = 7
- 输出: 0
- 解释: 不存在以 7 作为最大公因数的子数组。
提示
1 <= nums.length <= 10001 <= nums[i], k <= 109
代码
感觉有点考验数学能力。思路如下,先找到从l到r这个区间都是k的倍数,r+1就不是了,然后计算l到r中有多少种符合条件的情况,这段暴力求就可以过了。
class Solution {
public int subarrayGCD(int[] nums, int k) {
int res = 0;
int l = 0;
int r = 0;
while (r < nums.length) {
while (r < nums.length && nums[r] % k == 0) {
r++;
}
if (r > l) {
res = res + fun(r, l, nums, k); //l 到 r-1都是k的倍数
}
while (r < nums.length && nums[r] % k != 0) {
r++;
}
l = r;
}
return res;
}
//计算l 到r -1 中有多少符合的情况。
private int fun(int r, int l, int[] nums, int k) {
int res = 0;
for (int star = l; star < r; star++) {
for (int end = star; end < r; end++) {
if (nums[end] == k) {
res = res + r - end;
break;
}
if (end == star && nums[star] == k) {
res++;
}
if (check(nums, star, end,k)) {
res = res + r - end;
break;
}
}
}
return res;
}
private boolean check(int[] nums, int star, int end , int k) {
for (int i = star; i <= end; i++) {
for (int j = star + 1; j <= end; j++) {
if (way(nums[i],nums[j]) == k) {
return true;
}
}
}
return false;
}
public static int way(int m, int n) {
if (m == n) {
return n;
}
if (m > n && m % n == 0) {
return n;
} else {
return way(n, (m % n));
}
}
}
3.结束
又是掉分的一场周赛,第三题就不会了。现在居然是个二题选手了,太难过了,怎么感觉越来有越菜了。gogogo,刷题刷题,每天一道,三年1000道!!!!