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
}
原文地址:https://www.cnblogs.com/dubinyang/p/12099413.html