1. 程式人生 > >統計[0, 1, 2, ... , n]中k出現的次數,其中k為0-9任意數.

統計[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=3
    3=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; }