剑指Offer:面试题32——从1到n整数中1出现的次数(java实现)
2016-07-08 17:10
696 查看
问题描述:
输入一个整数n,求1到n这n个整数的十进制表示中1出现的次数。例如输入12,从1到12这些整数中包含1的数字有1,10,11,12,1一共出现了5次。
思路:(不考虑时间效率的解法,肯定不是面试官期望的)
直观想法:累加1到n中每个整数中1出现的次数。
每个整数中1出现的次数可以由除以10和模10来计算得到。
代码如下:
思路2:从数字规律着手明显提高时间效率的解法,能让面试官耳目一新
首先将1-n根据最高为分成两段,比如1-21345,分为1-1345与1346-21345
从最高位开始,每次分析最高位出现1的次数(用字符串)。然后剥去最高位进行递归求解。
代码:
输入一个整数n,求1到n这n个整数的十进制表示中1出现的次数。例如输入12,从1到12这些整数中包含1的数字有1,10,11,12,1一共出现了5次。
思路:(不考虑时间效率的解法,肯定不是面试官期望的)
直观想法:累加1到n中每个整数中1出现的次数。
每个整数中1出现的次数可以由除以10和模10来计算得到。
代码如下:
boolean invalidInput = false; //不考虑时间效率的解法 public int NumberOf1Between1AndN_Solution(int n) { if(n <= 0){ invalidInput = true; return 0; } int number = 0; for(int i = 1; i <= n; i++){ number += NumberOf1(i); } return number; } public int NumberOf1(int n){ int number = 0; while(n > 0){ if(n % 10 == 1){ number++; } n = n/10; } return number; }
思路2:从数字规律着手明显提高时间效率的解法,能让面试官耳目一新
首先将1-n根据最高为分成两段,比如1-21345,分为1-1345与1346-21345
从最高位开始,每次分析最高位出现1的次数(用字符串)。然后剥去最高位进行递归求解。
代码:
public class Solution { boolean invalidInput = false; //时间复杂度为O(logn) public int NumberOf1Between1AndN_Solution(int n) { if(n <= 0){ invalidInput = true; return 0; } StringBuilder s = new StringBuilder(((Integer)n).toString()); return NumberOf1(s); } int NumberOf1(StringBuilder s){ if(s == null || s.length() == 0 || s.charAt(0) < '0' || s.charAt(s.length()- 1) > '9'){ return 0; } int first = s.charAt(0) - '0'; int length = s.length(); if(length == 1 && first == 0){ return 0; } if(length == 1 && first > 0){ return 1; } //假设n = 21345 //numFirstDigit是数字10000 - 19999 的第一个位中的数目 int numFirstDigit = 0; if(first > 1){ numFirstDigit = PowerBase10(length - 1); }else if(first == 1){ numFirstDigit = Integer.parseInt(s.substring(1)) + 1; } //numOtherDigits是1346 - 21345除了第一位之外的数位中的数目 int numOtherDigits = first * (length - 1) * PowerBase10(length - 2); //numRecursive是1 - 1345中的数目 int numRecursive = NumberOf1(s.deleteCharAt(0)); return numFirstDigit + numOtherDigits + numRecursive; } int PowerBase10(int n){ int result = 1; for(int i = 0; i < n; i++){ result *= 10; } return result; } }
相关文章推荐
- 做一名合格的程序员
- 一个程序员的进化史-第八章
- 一个程序员的自白
- 【那些年遇到过的面试题】grep和find的区别
- 面试题28:字符串全排列
- 剑指Offer:面试题31——连续子数组的最大和(java实现)
- 剑指offer面试题5:从尾到头打印链表
- 剑指offer-4-面试24:二叉搜索树的后序遍历序列
- 怎么区别java程序员技术级别?
- 剑指Offer:面试题30——最小的k个数(java实现)
- 软件测试&软件测试工程师
- 15 张令人喷饭的 IT 趣图(第1季)
- [面试题] 替换空格和清除空格
- 面试题2
- 面试题2
- 面试题
- 面试题
- 59条令人捧腹但真实的程序员编程语录
- 剑指offer面试题4:替换空格
- 剑指offer之面试题14:调整数组顺序使得奇数位于偶数前面