leetcode hard模式专杀之233. Number of Digit One

本文介绍了一种计算从1到给定数字n中包含数字1的次数的方法。通过精细地划分数字位数并针对每种情况进行讨论,实现了高效计算。文章提供了一段Java代码实现,该实现关注于如何有效计算特定数字出现的频率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这道题思路很快就有了,但提交了七八次才通过,总结下来,是自己对数字计算可能还是不够敏感,导致边界条件总是考虑不周,不过总算独立完成了,足够犒赏自己一笔钱了,嘿嘿。思路如下:比如有一个数123, 可以这样计算,设定个位数为1,满足条件的其他位数上的组合有n0个,再假设十位数上的数字是1,满足条件的其他位数上的组合有n1个,再假设百位上的数字位1,满足条件的其他位数上的组合为n3,则最终的结果为n1+n2+n3,那么问题来了,怎么求满足条件的组合数呢?这就是这个问题的复杂性了,经过仔细考虑和试错,有三种情况要考虑,第一种第k位上的数字本身就>1,第二种==1,第三种<1,分三种情况讨论即可。然后还要注意各位数的情况。计算组合数的时候,尽量用整数运算,而不要用什么字符串遍历,否则时间复杂度是过不去的。不废话了,上代码:


public class Solution {
    public int minusOneAt(int num, int position){
		return num-(int)Math.pow(10, position);
	}
	
	public int strip(int num, int position){
		int tenth = (int)Math.pow(10, position);
		if((num/(int)Math.pow(10, position))%10 > 1){
			if(position == 0){
				return num/10;
			}
		//	return (num/(tenth*10))*10+num%tenth;
			return ((num/tenth)/10)*tenth+(int)Math.pow(10, position)-1;
		}else if((num/(int)Math.pow(10, position))%10 == 1){
			if(position == 0){
				return num/10;
			}
			return ((num/tenth)/10)*tenth+num%tenth;
		}else{
			int newNum = minusOneAt(num, position);
			if(position == 0){
				return newNum/10;
			}
			return ((newNum/tenth)/10)*tenth+(int)Math.pow(10, position)-1;
		}
	}
	
    public int countDigitOne(int n) {
    	int num = n;
        int digitCnt = 0;
        while(num>0){
        	digitCnt+=1;
        	num = num/10;
        }
        int result = 0;
        for(int i = 0; i < digitCnt; i++){
        	int afterStrip = strip(n, i);
        	result += afterStrip+1;
        }
        return result;
    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值