經典算法——Number of Digit One

Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n.

For example:
Given n = 13,

Return 6, because digit 1 occurred in the following numbers: 1, 10, 11, 12, 13.

一、題目描述:

給定一個十進制正整數n,寫下從1開始,到n的所有整數,然後統計其中出現的所有“1”的個數。

例如:

n=13.

其中包含1的數字有1,10,11,12,13,一共有6個“1”,所以輸出結果爲6.

二、解題思路:

方法1:從1開始遍歷到n,將其中每一個數中含有“1”的個數加起來,就會得到從1到n所有“1”的個數的和。




但是這種方法的時間複雜度爲nlogn,當n較大時,運行時間會很長。


方法2:利用數學歸納法,直接對n進行分析,歸納總結規律

例如n=abcde五位數,我們分析百位的c,主要有以下三種情況:

1)當c == 0的時候,比如13013,此時百位出現1的是:00 100 ~ 00 199, 01 100~01 199,……,11 100~ 11 199,12100~12199共1300個,顯然這個由高位數字決定,並且受當前位數影響,結果爲:(高位數字)乘以(當前位數);
2)當c == 1的時候,比如13113,此時百位出現1的肯定包括c=0的情況,另外還需要考慮低位的情況即:00100 ~ 00113共114個,結果爲:(高位數字)乘以(當前位數)+(低位數字)+1;
3)當c >= 2的時候,比如13213,此時百位出現1的是:00 100 ~ 00 199, 01 100~01 199,……,11 100~ 11 199,12 100 ~ 12 199,13100~13199,共1400個,這個僅由高位數字決定,結果爲:(高位數字+1)乘以當前位數。




class Solution {
public:
	int countDigitOne(int n) {
		if (n <= 0)  return 0;
		long count = 0;
		long factor = 1;

		while (n / factor)
		{
			long lower = n%factor;
			long cur = (n / factor) % 10;
			long higher = n / (factor * 10);

			switch (cur)
			{
			case 0:
				count += higher*factor;
				break;
			case 1:
				count += higher*factor + lower + 1;
				break;
			default:
				count += (higher + 1)*factor;
			}
			factor *= 10;
		}
		return (int)count;
	}
};


發佈了157 篇原創文章 · 獲贊 82 · 訪問量 66萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章