题目描述
- 写数字:
- 数位DP(太难了)
- 给定一个正数N,表示你在纸上写下1~N所有的数字
- 返回在书写的过程中,一共写下了多少个1
- 举例:
- N = 7 (1,2,3,4,5,6,7) 返回 1
- N = 13 (1,2,3,4,5,6,7,8,9,10,11,12,13) 返回 6
code
public class Code36 {
/**
* 假设一个数是N,一共有K位
* <p>
* 最高位是1 : (n % 10^(k-1) + 1) + (10^(K-2) * (k-1) * 1)
* 最高位不是1: 10(k-2次方) * (k-1) * first
*/
public static int oneNumber(int num) {
if (num < 1) {
return 0;
}
// num -> 13625
// len = 5位数
int len = getLenOfNum(num);
if (len == 1) {
return 1;
}
// num 13625
// tmp1 10000
// num 7872328738273
// tmp1 1000000000000
int tmp1 = powerBaseOf10(len - 1);
// num最高位 num / tmp1
int first = num / tmp1;
// 最高1 N % tmp1 + 1
// 最高位first tmp1
int firstOneNum = first == 1 ? num % tmp1 + 1 : tmp1;
// 除去最高位之外,剩下1的数量
// 最高位1 10(k-2次方) * (k-1) * 1
// 最高位first 10(k-2次方) * (k-1) * first
int otherOneNum = first * (len - 1) * (tmp1 / 10);
return firstOneNum + otherOneNum + oneNumber(num % tmp1);
}
/**
* 统计这个数有几位
*/
public static int getLenOfNum(int num) {
int len = 0;
while (num != 0) {
len++;
num /= 10;
}
return len;
}
public static int powerBaseOf10(int base) {
return (int) Math.pow(10, base);
}
}