题目:输入一个整数n,从1到n这n个十进制整数中1出现的次数。

思路1:对1到n中的任意一个数i对其进行求余数来判断个位是否为1,然后再求除数,判断十位是否为1.统计出1的个数。然后对1到n用一个循环将所有的数都加起来。时间复杂度为O(nlogn).

思路2:根据数字的规律来求。例如:21344这个数,我们将它分成两部分,第一部分为1345~21344.这部分我们可以先求出最高位上一出现的次数。又分为两种情况,10000~19999这种情况下最高位大于1,1出现的次数为10^4,另一种是10000~13456.1出现的次数为3456+1。第二部分为1~1344。采用递归完成。这种思路时间复杂度为O(logN)。

思路1:Java代码

//从1到n个整数中1出现的次数。时间复杂度为O(nlogn)
public class NumberOf1 {
public int number(int n){
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/=10;
}
return number;
}
public static void main(String[] args){
int n=213;
NumberOf1 no1=new NumberOf1();
int number=no1.number(n);
System.out.println(number);
}
}

思路2:Java代码

//从1到n的整数中,1出现的次数。从数字规律着手提高时间效率例如数字21456
//我们可以把该数字分为两部分,一部分是1到1456,另一不部分为1457到21456.
//首先看一下最高位为1的情况,分为两种,第一种10000到19999,最高位为1的数总共有10^4个。
//第二种10000到12345,那么就是23456个了。我们接下来看一下排列组合剩下的四为数中出现1
//的次数最高位为2,剩下四位中有一位为1,其他的三位符合排列组合0到9中任选一位,总和就是2*4*10^3。
//这种思路,每次做递归的时候就去掉一位,一个数字n有logN位。因此时间复杂度为O(logN)
public class NumberOf1BetweenN {
public int numberOf1(int n){
if(n<=0)
return 0;
String number=String.valueOf(n);
char[] numbers=number.toCharArray();
return numberOf1BetweenN(numbers,0);
} public int numberOf1BetweenN(char[] numbers, int i) {
if(numbers==null||i>numbers.length||i<0)
return 0;
//处理的第一个数字
int first=numbers[i]-'0';
int firstNumber=0;
//处理的数字的位数
int len=numbers.length-i;
//当只有一位数的时候
if(len==1&&first==0)
return 0;
if(len==1&&first>0)
return 1;
if(first>1){
firstNumber=powerBase10(len-1);
}
else if(first==1)
firstNumber=autoi(numbers,i+1)+1;
//处理剩下的位数
int otherNumber=first*(len-1)*powerBase10(len-2);
//处理1到1456这部分数字
int reverseNumber=numberOf1BetweenN(numbers,i+1);
return firstNumber+otherNumber+reverseNumber;
}
//将字符串数组转换为数字
public int autoi(char[] numbers, int i) {
if(numbers==null)
return 0;
int result=0;
for(int j=i;j<numbers.length;j++){
result=result*10+numbers[j]-'0';
}
return result;
} public int powerBase10(int n) {
int result=1;
for(int j=0;j<n;j++){
result*=10;
}
return result;
}
public static void main(String[] args){
int n=213;
NumberOf1BetweenN nobn=new NumberOf1BetweenN();
int numbersOf1=nobn.numberOf1(n);
System.out.println(numbersOf1);
}
}

剑指offer-第五章优化时间和空间效率(从1到n的整数中1出现的次数)的更多相关文章

  1. 剑指offer-第五章优化时间和空间效率(数组中的逆序对的总数)

    题目:在数组中如果两个数字的前面的数比后面的数大,则称为一对逆序对.输入一个数组求出数组中逆序对的总数. 以空间换时间:思路:借助一个辅助数组,将原来的数组复制到该数组中.然后将该数组分成子数组,然后 ...

  2. 剑指offer-第五章优化时间和空间效率(数组中出现次数超过一半的数字)

    题目:输入一个数组,找出一个数字,它在数组中出现的次数超过数组的一半. 题目规定如果可以改变数组中元素的位置. 思路1:如果数组是排序的,那么中间元素的位置不就是次数超过数组一半的元素吗?是的,因此我 ...

  3. 剑指offer-第五章优化时间和空间效率(把数组排列成最小的数)

    题目:输入一个正整数数组,将所有的数,排列起来,组成一个最小的数.

  4. 剑指offer-第五章优化时间和空间效率(两个链表的第一个公共节点)

    思路1:要求的是两个链表的第一个公共节点,首先想到的是用栈来存放两个链表,然后依次从栈中抛出,直到最后一个相同的节点为止.但是要用到两个栈,空间复杂度为O(n): 思路2:从头到尾分别遍历两个链表得到 ...

  5. 剑指offer-第五章优化时间和空间效率(在字符串中第一次出现切只出现一次的字符)

    题目:在字符串中第一次出现切只出现一次的字符 思路:用HashMap来存放对应的char值和该char出现的次数.做一次变量就可以得到第一个只出现一次的字符. Java代码: import java. ...

  6. 剑指offer-第五章优化时间和空间效率(连续子数组的最大和)

    题目:输入一个数组,数组中有正也有负,数组中连续的一个或者连续的多个数字组成一个子数组.求所有的子数组和的最大值.要求时间复杂度为O(n) 思路:我们的最直观的想法就是求出这个数组中的所有的子数组,然 ...

  7. 剑指offer-第五章优化时间和空间效率(最小的k个数)

    题目:输入n个数,输出最小的k个数. 时间复杂度为O(n) 思路1:我们想的到的最直接的思路就是对这个N个数进行排序,然后就可以找到最小的k个了,同样可以用快排partition.但是只要找到前K个最 ...

  8. 剑指offer第五章

    剑指offer第五章 1.数组中出现次数超过一半的数 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组 ...

  9. 剑指offer-第5章优化时间和空间效率(丑数)

    题目:我们把只包含因子2,3,5的数叫做丑数.寻找第1500个丑数.通常把1当成第一个丑数. 思路1:第一步判断是否为丑数:丑数是只包含2,3,5的数,因此一定可以被2,3,5整除.通过求余数是否为零 ...

随机推荐

  1. discuz对PHP7不支持mysql的兼容性处理

    PHP7 废除了 ”mysql.dll” ,推荐使用 mysqli 或者 pdo_mysql,discuz对原生mysql函数做了如下处理,通过mysqli代替原mysql函数 http://blog ...

  2. MYSQL提权的各种姿势

    一.利用mof提权 前段时间Kingcope大牛发布了mysql远程提权0day,剑心牛对MOF利用进行了分析,如下: Windows 管理规范 (WMI) 提供了以下三种方法编译到 WMI 存储库的 ...

  3. linux 进阶命令___0002

    #列出重复文件,首先检查文件大小,再检查md5sum find -not -empty -type f -printf "%s\n" | sort -rn | uniq -d | ...

  4. Java程序执行Linux命令(JSP运行其他程序)

    java程序中要执行linux命令主要依赖2个类:Process和Runtime 首先看一下Process类: ProcessBuilder.start() 和 Runtime.exec 方法创建一个 ...

  5. linux ioctl()函数

    我这里说的ioctl函数是指驱动程序里的,因为我不知道还有没有别的场合用到了它,所以就规定了我们讨论的范围.写这篇文章是因为我前一阵子被ioctl给搞混了,这几天才弄明白它,于是在这里清理一下头脑. ...

  6. Java中的比较运算符

    比较运算符用于判断两个数据的大小,例如:大于.等于.不等于.比较的结果是一个布尔值( true 或 false ). Java 中常用的比较运算符如下表所示: 注意哦: 1.  > . < ...

  7. Red Hat OpenStack 10的新特性

    这是Red Hat有史以来最好的版本,同时也是第一个长生命周期版本(最长五年支持),这篇文章会介绍为什么这是你私有云最好的礼物. 由于要使用命令行,以前安装OpenStack是很繁重的工作.这个版本提 ...

  8. bootstrap框架:常用内容一

    <!DOCTYPE html><html lang="zh-CN"> <head> <meta charset="utf-8&q ...

  9. spring mvc:复选框(多选)

    以user为例,user下有 username用户,password密码, address地址, receivePaper是否订阅, favotireFramework兴趣爱好, user.java ...

  10. angular指令(二)--内置指令

    一.基础ng 属性指令:  ng-href ng-src ng-disabled ng-checked ng-readonly ng-selected ng-class ng-styl ...