经典算法——Number of Digit One

Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n.

For example:
Given n = 13,

Return 6, because digit 1 occurred in the following numbers: 1, 10, 11, 12, 13.

一、题目描述:

给定一个十进制正整数n,写下从1开始,到n的所有整数,然后统计其中出现的所有“1”的个数。

例如:

n=13.

其中包含1的数字有1,10,11,12,13,一共有6个“1”,所以输出结果为6.

二、解题思路:

方法1:从1开始遍历到n,将其中每一个数中含有“1”的个数加起来,就会得到从1到n所有“1”的个数的和。




但是这种方法的时间复杂度为nlogn,当n较大时,运行时间会很长。


方法2:利用数学归纳法,直接对n进行分析,归纳总结规律

例如n=abcde五位数,我们分析百位的c,主要有以下三种情况:

1)当c == 0的时候,比如13013,此时百位出现1的是:00 100 ~ 00 199, 01 100~01 199,……,11 100~ 11 199,12100~12199共1300个,显然这个由高位数字决定,并且受当前位数影响,结果为:(高位数字)乘以(当前位数);
2)当c == 1的时候,比如13113,此时百位出现1的肯定包括c=0的情况,另外还需要考虑低位的情况即:00100 ~ 00113共114个,结果为:(高位数字)乘以(当前位数)+(低位数字)+1;
3)当c >= 2的时候,比如13213,此时百位出现1的是:00 100 ~ 00 199, 01 100~01 199,……,11 100~ 11 199,12 100 ~ 12 199,13100~13199,共1400个,这个仅由高位数字决定,结果为:(高位数字+1)乘以当前位数。




class Solution {
public:
	int countDigitOne(int n) {
		if (n <= 0)  return 0;
		long count = 0;
		long factor = 1;

		while (n / factor)
		{
			long lower = n%factor;
			long cur = (n / factor) % 10;
			long higher = n / (factor * 10);

			switch (cur)
			{
			case 0:
				count += higher*factor;
				break;
			case 1:
				count += higher*factor + lower + 1;
				break;
			default:
				count += (higher + 1)*factor;
			}
			factor *= 10;
		}
		return (int)count;
	}
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值