[杨小白]_leetcode_力扣第 316 场周赛-力扣-第二题

90 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第28天,点击查看活动详情

前言

小白算法比较菜,希望能激励我每日更新,从leetcode第一题开始,2022年目标300题,记录从0到1的全过程!!

力扣第 316 场周赛-力扣

力扣第 316 场周赛-力扣

这次第三题就是hard,想破头也没想出来。直接掉大分啊!当时看第二题太复杂就先去看第三题了,早知道先把第二题做了,说不定还能不掉分。。

image.png

第315双周赛的排名 image.png

第314双周赛的排名 image.png

第313周赛的排名

image.png

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 <= 1000
  • 1 <= 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道!!!!