牛客刷题Java实现---整数中1出现的次数(从1到n整数中1出现的次数)

本文介绍了一个算法,用于计算从1到任意非负整数n中数字1出现的总次数。通过遍历每个数并检查每一位是否为1来实现,适用于解决如求100~1300间1的出现次数等问题。

求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。

public class Solution {
	public static void main(String[] args) {
		int n=1;
		Solution s = new Solution();
		System.out.println(s.NumberOf1Between1AndN_Solution(n));
	}
	public int NumberOf1Between1AndN_Solution(int n) {
		int number=0;
		for(int i=1;i<=n;i++){        //遍历1~n
			number+=NuberOf1(i);
		}
		return number;
    }
	public int NuberOf1(int n){        //分别判断每一个数包含1的个数
		int number=0;
		while(n!=0){
			if(n%10==1){
				number+=1;
			}
			n/=10;
		}
		return number;
	}
}


 

<think>好的,我现在需要解决用户的问:给定一个正整数数组,计算它们的乘积g,然后找到最大的自然数k,使得g能被2^k整除。同时,用户希望找到类似牛客网的目。我需要先理解问,然后思考解决方法,再考虑如何解释清楚,最后推荐类似目。 首先,问分析。用户给了一个数组,要求乘积g,然后找到最大的k使得2^k整除g。这实际上是在问g的质因数分解中,2的指数是多少。例如,如果g=8=2^3,那么k=3。因此,问转化为求乘积中2的因子的总个数。 但是直接计算乘积可能会有溢出问,特别是当数组很大或者元素很大时,乘积会超出普通数据类型的范围。所以必须找到一个不需要实际计算乘积的方法。 这时候想到,每个a_i分解质因数中的2的个数,然后将所有a_i中的2的个数相加,总和就是k的最大值。例如,数组中的每个数可以分解为2的幂次乘以奇数,比如a_i = 2^b * c,其中c是奇数。那么总共有sum(b_i)个2相乘,因此k就是这个sum。 所以问转化为:对数组中的每个元素,计算其包含的2的因子数目,然后将这些数目相加,得到的总和就是最大的k。 那具体怎么实现呢?例如,对于一个数x,计算它能被2整除的次数,可以用循环除以2直到余数不为0为止,记录次数。或者用位运算,比如找出x二进制中最低位的1的位置,不过这可能比较复杂,还是用循环更直观。 接下来考虑可能的类似目。牛客网或其他平台的目可能有类似求质因数分解后的某个指数的最大值,或者类似分解每个元素的因数,求和的问。 比如,可能类似的问有: 1. 给定数组,求所有数的乘积末尾有多少个零。这需要计算乘积中10的因子数,即min(2的个数,5的个数)。这和本类似,但需要同时处理2和5,取最小值。 2. 求某个数的二进制表示中1个数,或者某个数的因子中2的最大幂次。这类目可能出现在位运算或数学中。 3. 另一个类似的问可能是,求数组元素的因子中某个质数的总指数,比如求所有数的3的因子总和。这和本类似,只是质数换成3。 现在,我需要给出解决用户问的步骤,并推荐类似的目。 首先,步骤: 1. 遍历数组中的每个元素。 2. 对于每个元素,计算其中包含多少个2的因子。例如,对每个数不断除以2,直到不能整除,记录次数。 3. 将所有元素的次数相加,总和即为最大的k。 4. 这样处理避免了直接计算乘积,防止溢出。 例如,数组是[2,4,8],每个数的2的因子数目分别是1,2,3,总和是6,所以k=6。 现在需要考虑代码实现。例如,在Java中,可以写一个循环,对每个数进行分解: public int maxK(int[] nums) { int count = 0; for (int num : nums) { while (num % 2 == 0) { count++; num /= 2; } } return count; } 这样处理时间复杂度是O(n log a_i),因为每个数需要除以2直到奇数,每次除以2的时间复杂度是log2(a_i)。 接下来,关于类似目,我需要找牛客或LeetCode上的目。例如: - LeetCode 172. Factorial Trailing Zeroes:计算n!末尾零的数量,需要计算5的因子数,但类似思路。 - 牛客网可能有目,比如“求数组中所有元素的乘积中因子2的个数”,或者类似的分解质因数的目。 - 或者目类似分解质因数总和,比如求所有元素的质因数分解中某个质数的总和。 比如,在LeetCode中,可能没有完全相同的目,但类似的目可能需要分解质因数。或者可能在其他平台上有类似的问。 现在需要确认是否存在类似目,可能需要回忆或者查找。例如,在LeetCode的库中,172是关于阶乘后的零,与本思路类似,但针对阶乘和10的因子。另外,比如目如“给定一个整数数组,返回每个数的因数中包含的2的个数的总和”可能类似。 此外,可能有一些目需要计算个数中某个质因数的总个数,比如分解每个数的质因数,然后累加某个质数的指数。 因此,用户的问可以转化为求数组中每个元素的2的因子数目之和,而类似的问可能涉及其他质数,或者不同的应用场景,如末尾零的数量。 总结,用户的解决方案是计算每个元素的2的因子数总和,而类似目可能包括: 1. 计算数组乘积末尾的零的数量(需要计算2和5的最小值)。 2. 求阶乘中某个质因数的数目。 3. 其他分解质因数的总和问。 因此,在给出答案时,需要先解释问解法,然后推荐类似目,并给出每个目的关键点。</think>--- ### **问分析** 目要求:给定正整数数组 $a_1, a_2, \dots, a_n$,计算其乘积 $g$ 中最大的自然数 $k$,使得 $g \% 2^k = 0$。 **本质**:求乘积 $g$ 的质因数分解中,质数 $2$ 的指数总和。 --- ### **解决思路** 1. **直接思路**: 计算每个元素中 $2$ 的因子个数,累加所有元素的因子数总和。 - 例如,$a_i = 8 = 2^3$,则其贡献 $3$ 个 $2$ 的因子。 - **无需实际计算乘积**,避免溢出问。 2. **算法步骤**: - 遍历数组中的每个数 $a_i$。 - 对每个 $a_i$,不断除以 $2$,统计能整除的次数(即 $2$ 的因子数)。 - 将所有统计结果相加,得到最终 $k$。 --- ### **代码实现Java)** ```java public int maxPowerOfTwoFactor(int[] nums) { int totalTwos = 0; for (int num : nums) { while (num % 2 == 0) { totalTwos++; num /= 2; } } return totalTwos; } ``` **时间复杂度**:$O(n \log a_i)$,其中 $n$ 为数组长度,$a_i$ 为数组元素。 --- ### **类似牛客目推荐** 以下目与本的核心思路(质因数分解、因子计数)高度相关: #### **1. 阶乘后的零(LeetCode 172)** - **目**:计算 $n!$ 结果末尾有多少个零。 - **关键点**:零由因子 $2 \times 5$ 产生,需统计 $n!$ 中 $2$ 和 $5$ 的因子数,取最小值。 - **链接**:[LeetCode 172](https://leetcode.cn/problems/factorial-trailing-zeroes/) #### **2. 数组乘积中的后缀零(扩展)** - **目**:给定数组,求所有元素乘积的末尾有多少个零。 - **解法**:统计数组中所有数的 $2$ 和 $5$ 的因子总数,取较小者。 #### **3. 质因数分解总和(自拟)** - **目**:给定数组和一个质数 $p$,求所有元素中 $p$ 的因子总数。 - **示例**:输入 `nums = [4, 8, 12], p = 2`,输出 `4 + 3 + 2 = 9`。 #### **4. 最大公约数的因子数(牛客/LeetCode变种)** - **目**:求数组中所有数的最大公约数(GCD)的质因数分解中,某个质数的指数。 - **关键点**:GCD 的 $2$ 的指数是数组中每个数 $2$ 的指数的最小值。 --- ### **总结** - **核心技巧**:将乘积问转化为因子计数问,避免直接计算大数。 - **扩展方向**:可推广到其他质数(如 $3, 5$)或组合因子(如 $10 = 2 \times 5$)。 - **建议**:通过类似目巩固质因数分解、循环计数等基础操作。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值