【问题描述】[困难]

【解答思路】

1. 暴力 (超时)

逐个数统计’1’的数量
时间复杂度:O(N^2) 空间复杂度:O(1)

 public int countDigitOne(int n) {int count = 0;for(int i=1;i<=n;i++){int tmp = i;while(tmp>0){if(tmp%10==1){count++;}tmp/=10;}}return  count;}
2. 分类

思路一

如果n = 4560234
让我们统计一下千位有多少个 1
xyz 可以取 0 到 455, abc 可以取 0 到 999
4551000 to 4551999 (1000)
4541000 to 4541999 (1000)
4531000 to 4531999 (1000)

21000 to 21999 (1000)
11000 to 11999 (1000)
1000 to 1999 (1000)
总共就是 456 * 1000
如果 n = 4561234
xyz 可以取 0 到 455, abc 可以取 0 到 999
4551000 to 4551999 (1000)
4541000 to 4541999 (1000)
4531000 to 4531999 (1000)

1000 to 1999 (1000)
xyz 还可以取 456, abc 可以取 0 到 234
4561000 to 4561234 (234 + 1)
总共就是 456 * 1000 + 234 + 1
如果 n = 4563234
xyz 可以取 0 到 455, abc 可以取 0 到 999
4551000 to 4551999 (1000)
4541000 to 4541999 (1000)
4531000 to 4531999 (1000)

1000 to 1999 (1000)
xyz 还可以取 456, abc 可以取 0 到 999
4561000 to 4561999 (1000)
总共就是 456 * 1000 + 1000

public int countDigitOne(int n) {int count = 0;//依次考虑个位、十位、百位...是 1//k = 1000, 对应于上边举的例子for (int k = 1; k <= n; k *= 10) { // xyzdabcint abc = n % k;int xyzd = n / k;int d = xyzd % 10;int xyz = xyzd / 10;count += xyz * k;if (d > 1) {count += k;}if (d == 1) {count += abc + 1;}//如果不加这句的话,虽然 k 一直乘以 10,但由于溢出的问题//k 本来要大于 n 的时候,却小于了 n 会再次进入循环//此时代表最高位是 1 的情况也考虑完成了if(xyz == 0){break;}}return count;
}

思路二



时间复杂度:O(logN) 空间复杂度:O(1)

 public int countDigitOne(int n) {int digit = 1, res = 0;int high = n / 10, cur = n % 10, low = 0;while(high != 0 || cur != 0) {if(cur == 0) res += high * digit;else if(cur == 1) res += high * digit + low + 1;else res += (high + 1) * digit;low += cur * digit;cur = high % 10;high /= 10;digit *= 10;}return res;}
3. 递归

class Solution {public int countDigitOne(int n) {return f(n);}private int f(int n ) {if (n <= 0)return 0;String s = String.valueOf(n);int high = s.charAt(0) - '0';int pow = (int) Math.pow(10, s.length()-1);int last = n - high*pow;if (high == 1) {return f(pow-1) + last + 1 + f(last);} else {return pow + high*f(pow-1) + f(last);}}
}

【总结】

1.这道题属于数学的分类,需要找规律,没有一些通用的算法,完全靠分析能力,如果面试碰到很容易卡住。

看实例理解

2.细心分析 注意边界

参考链接:https://leetcode-cn.com/problems/1nzheng-shu-zhong-1chu-xian-de-ci-shu-lcof/solution/mian-shi-ti-43-1n-zheng-shu-zhong-1-chu-xian-de-2/

参考链接:https://leetcode-cn.com/problems/1nzheng-shu-zhong-1chu-xian-de-ci-shu-lcof/solution/javadi-gui-by-xujunyi/
参考链接:https://leetcode-cn.com/problems/number-of-digit-one/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-50/

[剑指offer]面试题第[43]题[Leetcode][第233题][JAVA][1~n整数中1出现的次数][找规律][递归]相关推荐

  1. 剑指Offer:面试题33——把数组排成最小的数(java实现)(未完待续)

    问题描述: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 思路1: ...

  2. (待补充)【n个骰子的点数】剑指offer——面试题43:n个骰子的点数

    剑指offer--面试题43:n个骰子的点数 [注意]此题再牛客网上没有OnlineJudge,在此补充解法. 题目:把n个骰子扔在地上,所有骰子朝上一面的点数之和为s.输入n,打印出s的所有可能的值 ...

  3. [剑指offer]面试题第[68-2]题[Leetcode][第236题][JAVA][二叉搜索树的最近公共祖先][递归]

    [问题描述][中等] 235/68-1 搜索二叉树 236/68-2 二叉树 [解答思路] 递归 时间复杂度:O(N) 空间复杂度:O(N) 情况 1. , 2. , 3. , 4. 的展开写法如下. ...

  4. [剑指offer]面试题第[57]题[Leetcode][第167题][JAVA][和为s的两个数字][两数之和][HashSet][二分][双指针]

    [剑指offer]面试题第[57]题[Leetcode][第167题][第1题] 有序无序之分 题目输出不同之分 以下解法按照[剑指offer]面试题第[57]题进行题解 [问题描述][简单] 输入一 ...

  5. 算法题001 剑指Offer 面试题三:二维数组中的查找

    剑指Offer题目1:二维数组中的查找 题目描述: http://ac.jobdu.com/problem.php?cid=1039&pid=0 在一个二维数组中,每一行都按照从左到右递增的顺 ...

  6. 【剑指Offer面试题】 九度OJ1510:替换空格

    c/c++ 中的字符串以"\0"作为结尾符.这样每一个字符串都有一个额外字符的开销. 以下代码将造成内存越界. char str[10]; strcpy(str, "01 ...

  7. 剑指offer 面试题三 找出数组中重复的数字

    1 import org.junit.Test; 2 3 import java.util.Arrays; 4 import java.util.HashSet; 5 6 public class D ...

  8. (补充)【打印1到最大的n位数】剑指offer——面试题12:打印1到最大的n位数

    剑指offer--面试题12:打印1到最大的n位数 此题在牛客网上没有OnlineJudge,在此补充两种做法. 参考网址:https://blog.csdn.net/yanxiaolx/articl ...

  9. 【有返回值的回溯】剑指offer——面试题67——机器人的运动范围(回溯法)

    剑指offer--面试题67:机器人的运动范围(回溯法) Solution1: 此题和66题均是典型的回溯法题目,对比记忆思路! class Solution {public:int movingCo ...

最新文章

  1. HMM 前向 后向 Viterbi算法讲解通透的
  2. 通过公历年计算天干地支
  3. 100多个Android Demo的整合
  4. Taurus.MVC 支持Asp.Net Core 的过程
  5. android 模拟器识别,一种基于符号的识别Android应用运行在模拟器中的方法与流程...
  6. 28个经过重新设计的著名博客案例
  7. info testing mysql_SQLMASQLMAP中文说明(linux版本)
  8. 想做数学建模?先看看这些MATLAB函数吧!
  9. Axure写PRD:倒推淘票票APP产品需求文档
  10. 在js、jsp文件中如何获取项目绝对路径
  11. 一个磁性窗体VCL组件的具体实现
  12. CCF201509-3 模板生成系统(100分)
  13. 【原】GitHub使用教程
  14. js 获取mac地址和IP地址
  15. ARVR | 5大AR应用程序开发工具简介
  16. 个人技术总结——Unity中角色动画制作及动画切换逻辑的实现
  17. 限制性立方样条(Restricted Cubic Spline)
  18. linux绘制进程树,Linux基础命令---显示树形进程pstree
  19. 配置Tomcat性能优化
  20. netcore 动软三层架构-急速开发框架 winfrom demo

热门文章

  1. 深入理解和应用display属性(一)
  2. shape的简单用法
  3. java httpclient发送json 请求 ,go服务端接收
  4. 构建之法第11、12章
  5. “四方定理”--蓝桥杯
  6. CSS的历史与工作原理
  7. 看看自己08年的基金是否能赚钱
  8. oracle 执行计划 ppt,oracle查看执行计划的方法
  9. php server 性能,PHP中:$_SERVER[‘REQUEST_TIME’]和 time()有什么区别,那个性能快!...
  10. gesturedetector.java_我的flutter代码中的GestureDetector不起作用