力扣周赛(326)

文章介绍了两个编程问题的解决方案:一是计算数组所有元素乘积的不同质因数数目,使用哈希表记录质因数;二是找到给定范围内最接近的两个质数,通过预处理存储质数并进行枚举找到最小差值。第三个问题是将字符串分割成不超过K的子字符串,通过字符转整数和累加判断是否超过限制。
摘要由CSDN通过智能技术生成

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

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

注意:

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

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

  • 质数 是指大于 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 。
  • 代码:C++
  • class Solution {
    public:
        int distinctPrimeFactors(vector<int>& nums) {
            int i,j=2,x=1;
            //哈希表
            unordered_set<int> se;
            for(i=0;i<nums.size();i++){
                j=2;
                x=nums[i];
                while(x>=j){
                    while(x%j==0){
                        x=x/j;
                        se.insert(j);
                    }
                    j++;
                }
           
            }
            //返回不同整数个数
            return se.size();
        }
    };

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

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

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

示例 1:

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

代码:C++

class Solution {
public:
    vector<int> closestPrimes(int left, int right) {
        const int MAXA = 1e6;

        // 预处理:求出所有小于等于 1e6 的质数
        static bool inited = false;
        static bool flag[MAXA + 10];
        static vector<int> prime;
        if (!inited) {
            inited = true;
            for (int i = 2; i * i <= MAXA; i++) if (!flag[i]) for (int j = i * 2; j <= MAXA; j += i) flag[j] = true;
            for (int i = 2; i <= MAXA; i++) if (!flag[i]) prime.push_back(i);
        }

        // 记录从 left 到 right 的所有质数
        auto it = lower_bound(prime.begin(), prime.end(), left);
        vector<int> vec;
        for (; it != prime.end(); it++) {
            if (*it > right) break;
            vec.push_back(*it);
        }

        // 枚举所有质数,求最优答案
        const int INF = 1e7;
        int ans1, ans2, best = INF;
        for (int i = 1; i < vec.size(); i++) {
            int det = vec[i] - vec[i - 1];
            if (det < best) ans1 = vec[i - 1], ans2 = vec[i], best = det;
        }
        if (best < INF) return {ans1, ans2};
        else return {-1, -1};
    }
};

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

代码(C++):

class Solution {
public:
    typedef long long LL;
    int minimumPartition(string s, int k) {
    // 记录子字符串个数
        LL an = 0;
        for(int i = 0; i < s.size();)
        {
            //记录位数  记录数值大小
            LL t = 0; LL sum = 0;
            //字符数字转换为整形数字
            sum = sum * 10 + (s[i] - '0');
            
            //进位
            while(sum <= k)
            {
                t ++;
                if(i + t == s.size()) break;
                 sum = sum * 10 + (s[i + t] - '0');
            }
            //卡于个位且数值大于限制数则不满足
            if(t == 0 && sum > k) return -1;
            else i += t, an ++;
        }
        return an;
    }
};

值得一提的是这里有一个小技巧:

将字符数字转换成整型数字

int a = ‘1’ - ‘0’;

进位的话

a = a * 10 + (‘2’ - ‘0’)

结果为12 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值