2021-07-19:给定一个正数N,比如N = 13,在纸上把所有数都列出来如下: 1 2 3 4 5 6 7 8 9 10 11 12 13,可以数出1这个字符出现了6次,给定一个正数N,如果把1~N都列出来,返回1这个字符出现的多少次。
福大大 答案2021-07-19:
1.最高位是1的情况。
1364:3651364,千位上是365个1,百位上有100个1,十位上有100个1,个位上有100个1。5364,千位上是1000个1,百位上有500个1,十位上有500个1,个位上有500个1。
2.最高位不是1的情况。
5364:365
代码用golang编写。代码如下:
package main import ( "fmt" "math" ) func main() { num := 21 ret := solution2(num) fmt.Println(ret) } // 1 ~ num 这个范围上,画了几道1 func solution2(num int) int { if num < 1 { return 0 } // num -> 13625 // len = 5位数 len2 := getLenOfNum(num) if len2 == 1 { return 1 } // num 13625 // tmp1 10000 // // num 7872328738273 // tmp1 1000000000000 tmp1 := powerBaseOf10(len2 - 1) // num最高位 num / tmp1 first := num / tmp1 // 最高1 N % tmp1 + 1 // 最高位first tmp1 firstOneNum := twoSelectOne(first == 1, num%tmp1+1, tmp1) // 除去最高位之外,剩下1的数量 // 最高位1 10(k-2次方) * (k-1) * 1 // 最高位first 10(k-2次方) * (k-1) * first otherOneNum := first * (len2 - 1) * (tmp1 / 10) return firstOneNum + otherOneNum + solution2(num%tmp1) } func getLenOfNum(num int) int { len2 := 0 for num != 0 { len2++ num /= 10 } return len2 } func powerBaseOf10(base int) int { return int(math.Pow10(base)) } func twoSelectOne(c bool, a int, b int) int { if c { return a } else { return b } }
执行结果如下: