標籤:style class blog code color 表
題目:輸入一個整數,求從1到n這個n個整數的十進位表示中1的出現次數
方法一:最直觀的解法 T(n) = O(nlgn)
int NumberOf1Between1AndN_Solution1(unsigned int n){ int number = 0; for(unsigned int i = 1; i <= n; ++ i) number += NumberOf1(i); return number;}int NumberOf1(unsigned int n){ int number = 0; while(n) { if(n % 10 == 1) number ++; n = n / 10; } return number;}
方法二:
假設N = abcde(N的十進位表示,e為個位)
如果要計算百位c出現1的次數,將會受到3個因素的影響:
(1) 百位上的數字
(2) 百位以下的數字(低位元字)
(3) 百位以上的數字(高位元字)
如果百位元字為0,百位出現1的次數取決於 其高位元字
比如 12013, 出現1的情況可能是:100-199 1100-1199 2100-2199 ..... 10100-10199 11100-11199
可以看到出現1時,低位(即cde)都是 100-199這100種情況,而高位(即ab兩位)從 0,1,2,3...11 剛好為12對,即高位元字12
所以:這時百位出現1的次數:高位元字12 × 當前位元100 = 1200
如果百位元字為1,百位出現1的次數取決於 其高位元字和低位元字
比如12113,先按照上面一種情況所述:100-199 1100-1199 2100-2199 ..... 10100-10199 11100-11199
這個時候百位為1,則 還有其他情況可以出現1:12100 12101 12102 12103 .....12113 (注意到高兩位都為12,低位從100到113,即低位13+1=14種情況)
所以:這時百位出現1的次數:高位元字12 × 當前位元100 + 低位元字13 + 1 = 1214
如果百位元字大於1,百位出現1的次數取決於 其高位元字
比如12213,按照第一種情況所述:100-199 1100-1199 2100-2199 ..... 10100-10199 11100-11199 12100-12199
注意:百位元字大於1,所以不要忘記了 12100-12199 這種情況
所以:這時百位出現1的次數:(高位元字12 + 1 )× 當前位元100 = 1300
int OneNum(const int num){ assert(num >= 0); int factor = 1; int count = 0; int curNumber = 0; int highNumber = 0; int lowNumber = 0; while (num / factor != 0) { lowNumber = num - (num / factor) * factor; // 低位元字 curNumber = (num / factor) % 10; // 當前位元字 highNumber = (num / factor) / 10; // 高位元字 switch (curNumber) { case 0 : count += highNumber * factor; break; case 1 : count += highNumber * factor + lowNumber + 1; break; default : count += (highNumber + 1) * factor; break; } factor *= 10; } return count;}