统计[0, 1, 2, ... , n]中k出现的次数,其中k为0-9任意数.

问题描述

统计[0, 1, 2, … , n]中k出现的次数,其中k为0-9任意数.

分析

最笨的方法就是for循环每个数,进行叠加计算,方法如下:

int digitCounts(int k, int n) {
	int sum = 0;
	for (int i = 0; i <= n; i++) {			//循环每一个数
		int num = i;
		while (num / 10 != 0) {				//判断数是否为0,做while循环
			if (num % 10 == k) {		//判断各位上的值是否为k,进行++
				sum++;
				num /= 10;
			}
		}
		if (num == k) {						//判断最高位的值是否为k,进行++
			sum++;
		}
	}
	return sum;
}

这样的做法,需要循环n次,还不包括内部的while循环,时间复杂度为O(n)

优化解法

例如:当n=12345,固定一位,假设固定位为百位.
假设

  1. k=43<k,百位上的数小于k时.固定百位上的数是4,则存在的数就是400-499,1400-1499,2400-2499,…,10400-10499,11400-11499,即出现12x100次,也就是高位数字x位数.
  2. k=33=k,百位上的数等于k时.固定百位上的数是3,则存在的数就是300-399,1300-1399,2300-1399,…,10300-10399,11300-11399,还要包括12300-12345这写数字.也就是高位数字x位数+低位数字+1.
  3. k=2时,即3>k,百位上的数大于k时.固定百位上的数是2,则存在的数就是200-299,1200-1299,…,10200-10299,11200-11299,12200-12299.也就是**(高位数字+1)x低位数字**.

同理可以的到个位,十位,千位,万位的统计数字.
特别需要关注的是最高位上,如果k=0时,最高位上不能为0,排除这种情况.
因此优化代码:

int digitCounts(int k, int n) {
	if (k == 0 && n < 10) {				//排除k为0,n为个位数的情况
		return 1;
	}
	int temp = n;
	int count = 0;
	int pow = 1;							//位数
	while (temp != 0) {				//不为0时一直循环
		int digit = temp % 10;		//获取位数上的数
		if (digit < k) {					//进行比较
			count += (temp / 10) * pow;			//高位数字*位数
		} else if (digit == k) {
			count += (temp / 10) * pow + (n - temp * pow + 1);		//高位数字*位数+低位数字+1
		} else {
			if (!(k == 0 && temp / 10 == 0)) {			//排除k=0,计算最高位时的情况
				count += (temp / 10 + 1) * pow;		//(高位数字+1)*位数
			}
		}
		
		temp /= 10;			//退一位
		pow *= 10;			//进一位
	}
	return count;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值