您的位置:首页 > Web前端

剑指offer——从1到n整数中1出现的次数(好题,新增的解法很好)

2017-06-22 16:35 197 查看
题目描述

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

思路:

一开始只想到很常规的思路。

然后发现,可以用类似动规的概念来做。将数字拆分成个、十、百..

首先从1位数开始,只有1个1。然后所有2位数,1+9*1+1*10(十位是1的情况,不考虑个位)。 所有3位数,20+9*20+1*100

输入的是一个带符号整数,所以最多有10位,可以先用这个方法得到一个基准值。

最笨的方法:

public class Solution {
public int NumberOf1Between1AndN_Solution(int n) {
String m = null;
int result = 0;
for(int i = 0; i<=n; i++){
m = String.valueOf(i);
for(int j =0 ; j<m.length(); j++){
if(m.charAt(j)=='1')
result++;
}
}
return result;

}
}


找规律的解法,但找了很久,要多结合例子找出规律。

public class Solution {
public int NumberOf1Between1AndN_Solution(int n) {
int[] base = new int[11];
base[0] = 0;
base[1] = 1;
for(int i = 2; i<11; i++){
base[i] = 9*base[i-1]+(int)Math.pow(10,i-1)+base[i-1];
} //得到的是n位数(9,99,999)时,带1的个数
int[] s = new int[10];
int j = 0;
int temp = n;
while(temp!=0){
s[j] = temp%10;
temp = temp/10;
j++;
}
int result = 0;
for(int i = j-1; i>=0; i--){
if(s[i]>1)
result += (int)Math.pow(10,i);
if(s[i]==1) {
result++;
for (int k = 0; k < i; k++)
result += s[k] * (int) Math.pow(10, k);
}

result += base[i]*s[i];
}
return result;
}
}


http://blog.csdn.net/yi_afly/article/details/52012593

递归的写法:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: