leetcode数论(2521. 数组乘积中的不同质因数数目)-质因素分解

前言

经过前期的基础训练以及部分实战练习,粗略掌握了各种题型的解题思路。现阶段开始专项练习。

数论包含最大公约数(>=2个数)、最大公约数性质、最小公倍数、区间范围质因素计数(最下间隔)、质因素分解、判断质数、平方根、立方根、互质、同余等等。

描述

给你一个正整数数组 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

实现原理与步骤

1.分析题干积的分解质因素和单个数字的质因素分解后的结果一致。

2.定义Set数据结果去重重复的质因素

3.枚举数组数据并分解质因素

4.分解质因素函数

实现代码

class Solution {
    public int distinctPrimeFactors(int[] nums) {
        Set<Integer> set=new HashSet();
        for(int i=0;i<nums.length;i++){
            getPrime(nums[i],set);
        }
        return set.size();
    }

    public void getPrime(int n,Set<Integer> set){
        while(n%2==0){
            set.add(2);
            n=n/2;
        }
        for(int i=3;i*i<=n;i+=2){
            while(n%i==0){
                set.add(i);
                n=n/i;
            }
        }
        if(n>2){
            set.add(n);
        }
        
    }
}

1.QA:

import scala.collection.mutable private val M = (1e9 + 7).toLong //一个大质数,用于取模运算,防止结果溢出。 private val MX = (1e5 + 1).toInt private val omega = Array.ofDim[Int](MX) // omega:一个数组,用于存储每个数的质因数个数。 // 使用埃拉托色尼筛法计算每个数的质因数个数。对于每个数i,如果omega(i)为0,则i是质数,然后更新i的倍数的质因数个数。 (2 until MX).foreach(i => if (omega(i) == 0) (i until MX by i).foreach(j => omega(j) += 1)) def maximumScore(nums: List[Int], k: Int): Int = { val arr = nums.toArray val n = arr.length val left = Array.fill(n)(0) val right = Array.fill(n)(n) val st = mutable.Stack[Int](-1) // 计算每个元素的左边界和右边界 // 使用单调栈计算每个元素的左边界和右边界。左边界是第一个比当前元素质因数个数小的元素的位置,右边界是第一个比当前元素质因数个数大的元素的位置。 arr.indices.foreach(i => { while (st.size > 1 && omega(arr(st.top)) < omega(arr(i))) right(st.pop()) = i left(i) = st.top st.push(i) }) val ids = Array.tabulate(n)(identity) val sortedIds = ids.sortWith((i, j) => arr(j) - arr(i) < 0) var res = 1L var remainingK = k sortedIds.foreach(i => { val tot = (i - left(i)).toLong * (right(i) - i) if (tot >= remainingK) { res = res * pow(arr(i), remainingK) % M remainingK = 0 } else { res = res * pow(arr(i), tot.toInt) % M remainingK -= tot.toInt } }) res.toInt } private def pow(x: Long, n: Int): Long = { var res = 1L var base = x var exp = n while (exp > 0) { if (exp % 2 > 0) res = res * base % M base = base * base % M exp /= 2 } res }帮我解释下
最新发布
04-02
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值