计算1到N中包含数字1的个数

今天看到一道有趣的算法题,题目如下:

N为正整数,计算从1到N的所有整数中包含数字1的个数。比如,N=10,从1,2...10,包含有2个数字1。

 

相信很多人都能立刻得出以下的解法:

  for(n:N)

  {

          判断n包含1的个数;

          累加计数器;

  }

这是最直接的解法,但遗憾的是,时间复杂程度为O(N*logN)。因为还需要循环判断当前的n的各位数,该判断的时间复杂程度为O(logN)。

接下来就应该思考效率更高的解法了。说实话,这道题让我想起另外一道简单的算法题:

N为正整数,计算从1到N的整数和。

很多人都采用了循环求解。然后利用初等数学知识就知道S=N*(N+1)/2,所以用O(1)的时间就可以处理。

再回到本道题目,同理应该去寻找到结果R与N之间的映射关系。

分析如下:

假设N表示为a[n]a[n-1]...a[1],其中a[i](1<=i<=n)表示N的各位数上的数字。

c[i]表示从整数1到整数a[i]...a[1]中包含数字1的个数。

x[i]表示从整数1到10^i - 1中包含数字1的个数,例如,x[1]表示从1到9的个数,结果为1;x[2]表示从1到99的个数,结果为20;

当a[1]=0时,c[1] = 0;

当a[1]=1时,c[1] = 1;

当a[1]>1时,c[1] = 1;

 

当a[2]=1时,c[2] = a[1] +1+ c[1] + x[1];

当a[2]>1时,c[2] = a[2]*x[1]+c[1]+10;

 

当a[3]=1时,c[3] = a[2]*a[1] +1+ c[2] + x[2];

当a[3]>1时,c[3] = a[3]*x[2]+c[2]+10^2;

......

 

以此类推

当a[i]=1时,c[i] = a[i-1]*...*a[1] +1+ c[i-1]+x[i-1];

当a[i]>1时,c[i] = a[i]x[i-1]+c[i-1]+10^(i-1);

 

 

实现的代码如下:

    public static int search(int _n)   
    {   
        int N = _n/10;   
        int a1 = _n%10,a2;   
        int x = 1;
        int ten = 10;
        int c = a1 == 0?0:1;
        while(N > 0)   
        {   
            a2 = N%10;
            if(a2 == 0);
            else if(a2 == 1)c = a1 + 1 + x + c;   
            else c = a2*x + c + ten;   
            a1 = 10*a1 + a2;     
            N /=10;   
            x = 10*x + ten;
            ten *= 10; 
        }   
        return c;   
    }

 

 

而以上解法的时间复杂程度只有O(logN)

 

如果您路过这里,您有更好的解法吗?:)

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这道题可以用数位DP的方法来解决。 首先,我们可以将n拆分成若干个数位,例如n=1234,可以拆分成1、2、3、4四个数位。 接下来,我们考虑如何计算个数位上包含数字1的个数。 对于一个数位来说,它可以分为三种情况: 1.该数位上的数字为0,例如1234的千位,那么它包含数字1的个数为0。 2.该数位上的数字为1,例如1234的百位,那么它包含数字1的个数为它前面的数字(即12)乘以当前数位的权值(即100),再加上它后面的数字(即34)加1(因为当前数位上的数字为1),即12*100+34+1=1235。 3.该数位上的数字大于1,例如1234的个位,那么它包含数字1的个数为它前面的数字(即123)乘以当前数位的权值(即1),再加上当前数位的权值(即1),即123*1+1=124。 最后,将每个数位上包含数字1的个数相加即可得到从1到n的所有整数包含数字1的个数。 举个例子,当n=1234时,它包含数字1的个数为: 千位:0 百位:12*100+34+1=1235 十位:12*10+10=130 个位:123*1+1=124 总数:0+1235+130+124=1489 因此,当n=1234时,从1到n的所有整数包含数字1的个数为1489个。 ### 回答2: 要计算从1到n的所有整数包含数字1的个数,我们可以遍历1到n的每个数字,然后判断该数字是否包含数字1。若包含1,则计数器加1。 例如,当n=10时,我们从1到10遍历每个数字: 对于数字1,包含1,计数器加1。 对于数字2,不包含1,计数器不变。 对于数字3,不包含1,计数器不变。 对于数字4,不包含1,计数器不变。 对于数字5,不包含1,计数器不变。 对于数字6,不包含1,计数器不变。 对于数字7,不包含1,计数器不变。 对于数字8,不包含1,计数器不变。 对于数字9,不包含1,计数器不变。 对于数字10,包含1,计数器加1。 因此,在1到10的所有整数包含数字1的个数为2个。 算法如下: 1. 初始化计数器count为0。 2. 从1到n遍历每个数字num。 3. 将num转换为字符串strNum。 4. 遍历strNum的每个字符char,若char等于字符'1',则计数器count加1。 5. 返回count作为结果。 使用该算法,可以计算出从1到n的所有整数包含数字1的个数。 ### 回答3: 要计算从1到n的所有整数包含数字1的个数,我们可以使用循环遍历的方法。 首先,我们定义一个变量count来表示包含数字1的个数,并将其初始化为0。 然后,我们使用一个循环从1迭代到n。在每次循环,我们将当前的数字转换为字符串,然后使用字符串的count方法来统计数字1在该字符串出现的次数,并将结果累加到count变量。 最后,循环结束后,我们可以得到从1到n的所有整数包含数字1的个数。 下面是一个实现的代码示例: ```python def count_ones(n): count = 0 for i in range(1, n+1): count += str(i).count('1') return count n = 10 result = count_ones(n) print(f"从1到{n}的所有整数包含数字1的个数为:{result}个") ``` 对于n=10的情况,运行结果为:从1到10的所有整数包含数字1的个数为:2个。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值