LeetCode 233.数字1的个数 Number of Digit One

题目链接

给定一个整数n,计算所有小于等于n的非负整数中数字1出现的个数。


0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49
50 51 52 53 54 55 56 57 58 59
60 61 62 63 64 65 66 67 68 69
70 71 72 73 74 75 76 77 78 79
80 81 82 83 84 85 86 87 88 89
90 91 92 93 94 95 96 97 98

99

我一开始的思路是,先计算个位1的个数,再计算高位1的个数。

扫描二维码关注公众号,回复: 4462431 查看本文章

个位1的个数好求,个位1的个数=(n%10>=1)?(n/10+1):(n/10)


就是高位1的个数我想的有些乱了。

比如,123和223,它们百位的1的个数分别是多少呢

123百位的1=123-100+1=24

223百位的1=100

于是可以知道,对于高位,是从==1和>1作为分界线。


可是,123和223,它们十位的1的个数分别是多少呢。在这里我想了很久。

高位将次高位分成了若干份

123,1百将十位分成了两份,0~99和100~123,相当于从0~99找1的个数*1+从0~23找1的个数

223,2百将十位分成了三份,0~99和100~199和200~223,相当于从0~99找1的个数*2+从0~23找1的个数

323,3百将十位分成了四份,0~99和100~199和200~299和300~323,相当于从0~99找1的个数*3+从0~23找1的个数


如果想通了这里,就很好理解了。


于是思路变了。

代码如下:

class Solution {
public:
int calculate(int n,int k)
{
	if(n<1)	return 0;
	if(n<10)	return 1;//当n只有1位的时候
	int c;
	while(1)//这里是为了保证k和n是相同位数
	{
		c=n/k;
		if(c!=0)	break;
		k/=10;
	}
	if(c==1)//当最高为为1的时候
	{
		return n-k+1+calculate(n-k,k/10)+calculate(k-1,k/10);//如果能理解最高位将次高位分成若干份这句话
	}
	else//当最高位>1的时候
	{
		return k+calculate(n-c*k,k/10)+c*calculate(k-1,k/10);
	}
}

int countDigitOne(int n) {
        int k=1;
        int m=n;
        while(m/=10)
        {
            k*=10;
        }
        return calculate(n,k);
    }
};






猜你喜欢

转载自blog.csdn.net/ZRXSLYG/article/details/80593717
今日推荐