【LeetCode】第 326 场周赛题解

153 阅读2分钟

6278. 统计能整除数字的位数

给你一个整数 num ,返回 num 中能整除 num 的数位的数目。 如果满足 nums % val == 0 ,则认为整数 val 可以整除 nums 。

示例 1:

输入: num = 7
输出: 1
解释: 7 被自己整除,因此答案是 1 。

示例 2:

输入: num = 121
输出: 2
解释: 121 可以被 1 整除,但无法被 2 整除。由于 1 出现两次,所以返回 2 。

示例 3:

输入: num = 1248
输出: 4
解释: 1248 可以被它每一位上的数字整除,因此答案是 4 。

 

提示:

  • 1 <= num <= 109
  • num 的数位中不含 0

题解:模拟

class Solution {
public:
    int countDigits(int num) {
        string s = to_string(num);
        int res = 0;
        for(auto c : s){
            if(num%(c-'0') == 0){
                res++;
            }
        }
        return res;
    }
};

6279. 数组乘积中的不同质因数数目

给你一个正整数数组 nums ,对 nums 所有元素求积之后,找出并返回乘积中 不同质因数 的数目。

注意:

  • 质数 是指大于 1 且仅能被 1 及自身整除的数字。
  • 如果 val2 / val1 是一个整数,则整数 val1 是另一个整数 val2 的一个因数。

 

示例 1:

输入: nums = [2,4,3,7,10,6]
输出: 4
解释:
nums 中所有元素的乘积是:2 * 4 * 3 * 7 * 10 * 6 = 10080 = 25 * 32 * 5 * 7 。
共有 4 个不同的质因数,所以返回 4 。

示例 2:

输入: nums = [2,4,8,16]
输出: 1
解释:
nums 中所有元素的乘积是:2 * 4 * 8 * 16 = 1024 = 210 。
共有 1 个不同的质因数,所以返回 1 。

 

提示:

  • 1 <= nums.length <= 104
  • 2 <= nums[i] <= 1000

题解: 质因数分解

class Solution {
public:
    int distinctPrimeFactors(vector<int>& nums) {
        unordered_set<int> s;
        for(auto num : nums){
            for(int i=2; i*i<=num; i++){
                if(num%i == 0){
                    s.insert(i);
                    while(num%i == 0) num/=i;
                }
            }
            if(num > 1) s.insert(num);
        }
        return s.size();
    }
};

6196. 将字符串分割成值不超过 K 的子字符串

给你一个字符串 s ,它每一位都是 1 到 9 之间的数字组成,同时给你一个整数 k 。

如果一个字符串 s 的分割满足以下条件,我们称它是一个  分割:

  • s 中每个数位 恰好 属于一个子字符串。
  • 每个子字符串的值都小于等于 k 。

请你返回 s 所有的  分割中,子字符串的 最少 数目。如果不存在 s 的  分割,返回 -1 。

注意:

  • 一个字符串的  是这个字符串对应的整数。比方说,"123" 的值为 123 ,"1" 的值是 1 。
  • 子字符串 是字符串中一段连续的字符序列。

示例 1:

输入: s = "165462", k = 60
输出: 4
解释: 我们将字符串分割成子字符串 "16""54""6""2" 。每个子字符串的值都小于等于 k = 60 。
不存在小于 4 个子字符串的好分割。

示例 2:

输入: s = "238182", k = 5
输出: -1
解释: 这个字符串不存在好分割。

提示:

  • 1 <= s.length <= 105
  • s[i] 是 '1' 到 '9' 之间的数字。
  • 1 <= k <= 109

题解:动态规划, f[i] 表示前 i 个字符分割最少数目。

class Solution {
public:
    int minimumPartition(string s, int k) {
       int n = s.size(), INF = 1e8;
       vector<int> f(n+1, INF);
       f[0] = 0;
       for(int i=1; i<=n; i++){
           long long t = 0, p = 1;
           for(int j=i; j; j--){
                t += p*(s[j-1]-'0');
                p*=10;
                if(t > k) break;
                f[i] = min(f[i], f[j-1]+1);
           }
           if(f[i] == INF) return -1;
       }
       return f[n];
    }
};

6280. 范围内最接近的两个质数

给你两个正整数 left 和 right ,请你找到两个整数 num1 和 num2 ,它们满足:

  • left <= nums1 < nums2 <= right  。
  • nums1 和 nums2 都是 质数 。
  • nums2 - nums1 是满足上述条件的质数对中的 最小值 。

请你返回正整数数组 ans = [nums1, nums2] 。如果有多个整数对满足上述条件,请你返回 nums1 最小的质数对。如果不存在符合题意的质数对,请你返回 [-1, -1] 。

如果一个整数大于 1 ,且只能被 1 和它自己整除,那么它是一个质数。

 

示例 1:

输入: left = 10, right = 19
输出: [11,13]
解释: 1019 之间的质数为 11131719 。
质数对的最小差值是 2[11,13][17,19] 都可以得到最小差值。
由于 1117 小,我们返回第一个质数对。

示例 2:

输入: left = 4, right = 6
输出: [-1,-1]
解释: 给定范围内只有一个质数,所以题目条件无法被满足。

 

提示:

  • 1 <= left <= right <= 106

题解:质数筛选

const int N = 1e6+5;
int primes[N], cnt;
bool st[N];
class Solution {
public:
   void get_primes(int n){
       cnt = 0;
       for(int i=2; i<=n; i++){
           if(!st[i]) primes[cnt++] = i;
           for(int j=0; primes[j]*i <=n; j++){
               st[primes[j]*i] = true;
               if(i%primes[j] == 0) break;
           }
       }
   }
    vector<int> closestPrimes(int left, int right) {
        get_primes(right);
        int diff = 1e8;
        vector<int> res(2, -1);
        for(int i=1; i<cnt; i++){
            int a = primes[i], b = primes[i-1];
            if(b >= left && a-b < diff){
                res[0] = b;
                res[1] = a;
                diff = a-b;
            }
        }
        return res;
    }
};