这题属于需要找规律的题。先想一下最简单的情形:N = 10^n - 1

记X[i]表示从1到10^i - 1中 1 的个数,则有如下递推公式:X[i] = 10 * X[i - 1] + 10^(i - 1)

这个递推公式可以这么观察得到:

i = 0, X[0] = 0

i = 1, 从1到9, X[1] = 1

i = 2, 从1到99, X[2] = 20:可以设想,把所有数都写成两位数(比如1写成01, 2写成02),我们暂且不统计最高位的1, 则首先至少有10 * X[1]个1,然后我们考虑最高位的1,它只存在于11,12...19,也是10个

i = 3,从1到999,X[3] = ? : 同样先不统计最高位的1,首先至少有10 * X[2]个1,再统计最高位,应该还要加上100(10^(3-1))

逐步思考,通项公式就出来了:X[i] = 10 * X[i - 1] + 10^(i - 1)

记我们要求解的函数为f(x)

现在我们考虑一般的N,假设它表示成10进制有n位:a[n]a[n-1]...a[1]

用C[i]表示f(a[i]a[i-1]...a[1])的结果

递推过程仍旧类似,但此时每一位的上限有了限制,不能自由的从0到9取值

a[i] = 0时,C[i] = C[i - 1]

a[i] = 1时:C[i] = X[i - 1] + C[i - 1] + a[i-1]a[i-1]...a[1] + 1

a[i] > 1时:C[i] = a[i] * X[i - 1] + 10 ^(i - 1) + C[i - 1]

class Solution {
public:
int countDigitOne(int n) {
  int base = 10;
  vector<int> digits;
  while (n >= 1) {
    digits.push_back(n % base);
    n /= base;
  }
  vector<int> nums;
  int s = 0;
  base = 1;
  for (int i = 0; i < digits.size(); i++) {
    s += base * digits[i];
    nums.push_back(s);
    base *= 10;
  }
  vector<int> C(digits.size() + 1, 0);
  vector<int> X(digits.size() + 1, 0);
  base = 1;
  for (int i = 1; i < C.size(); i++) {
    X[i] = 10 * X[i - 1] + base;
    if (digits[i - 1] == 0) {
      C[i] = C[i - 1];
    }
    else if (digits[i - 1] == 1) {
      C[i] = X[i - 1] + C[i - 1] + 1 + (i > 1 ? nums[i - 2] : 0);
    }
    else {
      C[i] = digits[i - 1] * X[i - 1] + C[i - 1] + base;
    }
    base *= 10;
}
return C[C.size() - 1];

}
};

leetcode 233 Number of Digit One的更多相关文章

  1. Java for LeetCode 233 Number of Digit One

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

  2. (medium)LeetCode 233.Number of Digit One

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

  3. LeetCode 233 Number of Digit One 某一范围内的整数包含1的数量

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

  4. 【LeetCode】233. Number of Digit One

    题目: Given an integer n, count the total number of digit 1 appearing in all non-negative integers les ...

  5. 233. Number of Digit One

    题目: Given an integer n, count the total number of digit 1 appearing in all non-negative integers les ...

  6. 233. Number of Digit One *HARD* -- 从1到n的整数中数字1出现的次数

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

  7. 233. Number of Digit One(统计1出现的次数)

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

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

    给定一个整数 n,计算所有小于等于 n 的非负数中数字1出现的个数. 例如: 给定 n = 13, 返回 6,因为数字1出现在下数中出现:1,10,11,12,13. 详见:https://leetc ...

  9. [LeetCode] Number of Digit One 数字1的个数

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

随机推荐

  1. <mvc:annotation-driven />

    <mvc:annotation-driven/>相当于注册了DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter两个 ...

  2. 关于js中变量声明和作用域的理解

    1. var是声明一个变量:虽然声明了这个变量,但在存入值之前,它的初始值是 undefined:2.全局变量:拥有全局作用域,在js代码中的任何地方都是有定义的:3.局部变量:在函数内声明的变量只在 ...

  3. HTML5自学笔记[ 12 ]canvas绘图小示例之鼠标画线

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  4. 关于byte[]字节传输的大端和小端小议

    当前的存储器,多以byte为访问的最小单元,当一个逻辑上的地址必须分割为物理上的若干单元时就存在了先放谁后放谁的问题,于是端(endian)的问题应运而生了,对于不同的存储方法,就有大端(big-en ...

  5. javaSE基础——常见的dos命令即其他

     常用的DOS命令 dir(directory) :    列出当前目录下的文件以及文件夹 md(make directory) : 创建目录 rd(remove directory) : 删除目录 ...

  6. MessageDigest简介

    一.概述 MessageDigest 类为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法.信息摘要是安全的单向哈希函数,它接收任意大小的数据,并输出固定长度的哈希值. MessageDi ...

  7. poj1129 Channel Allocation(染色问题)

    题目链接:poj1129 Channel Allocation 题意:要求相邻中继器必须使用不同的频道,求需要使用的频道的最少数目. 题解:就是求图的色数,这里采用求图的色数的近似有效算法——顺序着色 ...

  8. prepareStatement和Statement的区别

    1:创建时的区别:    Statement stm=con.createStatement();    PreparedStatement pstm=con.prepareStatement(sql ...

  9. ORACLE数据泵还原(IMPDP命令)【转】

      Oracle数据库还原IMPDP命令是相对于EXPDP命令的,方向是反向的.即对于数据库备份进行还原操作.一.知晓IMPDP命令 ? C:\>impdp -help Import: Rele ...

  10. CCF 2016-12 送货

    问题描述 试题编号: 201512-4 试题名称: 送货 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 为了增加公司收入,F公司新开设了物流业务.由于F公司在业界的良好口碑, ...