Go语言实现:【剑指offer】整数中1出现的次数(从1到n整数中1出现的次数)
该题目来源于牛客网《剑指offer》专题。
求出1 ~ 13的整数中1出现的次数,并算出100 ~ 1300的整数中1出现的次数?为此他特别数了一下1 ~ 13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。
举例说明:
234:个位,每个0-9里出现一次1,有23个0-9,个位(low)为4则有一个0-4,包含1,再加上1,23*1+1;
234:十位,每个0-9里出现一次1,有2个0-9,在十位所以乘10,十位(low)为3则有0-3,包含1则有10-19共10个1,2*10+10;
234:百位,每个0-9里出现一次1,有0个0-9,在百位所以乘100,百位(low)为2则有0-2,包含1则有100-199共100个1,0*100+100;
231:个位,每个0-9里出现一次1,有23个0-9,个位(low)为1则有一个0-1,包含1,再加上1,23*1+1;
214:十位,每个0-9里出现一次1,有2个0-9,在十位所以乘10,十位(low)为1则有0-1,包含1且个位为4,则有10到14共5个1,2*10+4+1;
134:百位,每个0-9里出现一次1,有0个0-9,在百位所以乘100,百位(low)为1则有0-1,包含1且十位个位为34,则有100到134共35个数,0*100+34+1;
当前位等于0:high * base
当前位等于1:high * base + low之前所有位+1
当前位大于1:high * base + base
Go语言实现:
//暴力查询
func numberOfBetween1AndN(n int) int {
count := 0
for n > 0 {
str := strconv.Itoa(n)
for _, v := range str {
if string(v) == "1" {
count++
}
}
n--
}
return count
}
//按位计算
func numberOfBetween1AndN(n int) int {
if n < 1 {
return 0
}
count := 0
low := 0
high := n
base := 1
for high > 0 {
low = high%10
high /= 10
count += high*base
if low == 1 {
count += n%base + 1
}
if low > 1 {
count += base
}
base *= 10
}
return count
}