zoukankan      html  css  js  c++  java
  • 剑指Offer——整数中1出现的次数(从1到n整数中1出现的次数)

    题目描述:

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


    分析:

     找规律。

     该数字(不包括该数)以内  出现1的次数
     1  0
     10  1
     100  20
     1000  300
     2  0+1+0=1
     20  1+10+1=12
     200  20+100+20=140
     2000  300+1000+300=1600
     3  1+0=1
     30  12+1=13
     300  140+20=160

    m*10^i这个数(不含这个数):

    如果m=1,那么这个数以内有(m*i*10^(i-1))个1。

    如果m>1,那么这个数以内有(m*i*10^(i-1)+10^i)个1。

    那么如果给出一个数,我们可以拆分每一位。

    例如给出的数是1213的话,那么我们可以求

    1000以内1的个数+200以内1的个数+10以内1的个数+3以内1的个数,

    另外我们还需要加上213再加上3,因为它们的前一个位数字都是1;而且我们还要再加上2,因为本身1213中有2个1,我们之前算的一直都是不含本身的。

    更加直观的讲就是,1213,求0~999中1的个数+1000~1199中1的个数+1200~1209中1的个数+1210~1212中1的个数+1213中1的个数。

    213从1000~1199、1200~1209、1210~1212中的第一个1来的。

    3从1210~1212中的第三个1来的。

    代码:

     1 class Solution {
     2 public:
     3     int NumberOf1Between1AndN_Solution(int n) {
     4         int n1 = n;
     5         int i = 0; // 0的个数
     6         int ei = 1; // 10^i
     7         int ans = 0;
     8         while(n1) {
     9             int m = n1 % 10; // 首位
    10             ans += m * i * ei / 10;
    11             if(m > 1) ans += ei;
    12             if(m == 1) ans += n % ei + 1;
    13             ei *= 10;
    14             i++;
    15             n1 /= 10;
    16         }
    17         return ans;
    18     }
    19 };
  • 相关阅读:
    中缀、后缀、前缀表达式
    Salesforce图片上传
    VSCode格式化Apex代码
    Reporting Services已有帐号出现无法登录的问题
    EF-查询缓存
    visual studio 2015将已有项目添加到码云(gitee)
    asp.net页面加载两次的坑
    EF的性能瓶颈
    微信JS-SDK上传多张照片
    Python20-Day02
  • 原文地址:https://www.cnblogs.com/jacen789/p/7747666.html
Copyright © 2011-2022 走看看