劍指Offer——面試題31:整數中1出現的次數
阿新 • • 發佈:2019-02-09
整數中1出現的次數(從1到n整數中1出現的次數)
題目:求出1~13的整數中1出現的次數,並算出100~1300的整數中1出現的次數?為此他特別數了一下1~13中包含1的數字有1、10、11、12、13因此共出現6次,但是對於後面問題他就沒轍了。ACMer希望你們幫幫他,並把問題更加普遍化,可以很快的求出任意非負整數區間中1出現的次數(從1 到 n 中1出現的次數)。
輸入:13
輸出:6
思路:舉一個例子來分析,就比較清晰了,比如1~2573中5出現的次數,我們從個位、十位然後依次分析。
對於2573的個位中會出現多少個5,主要看它前面有多少數字,即2573 / 10 = 257個,那麼就會出現257個5,因為從0開始,0~256,對於2573由於個位數小於5,所以只有257個
對於十位來說,因為它前面有2573 / 100 = 25個,而且每個十位的5,會有50~59這10個,所以總的來說,十位的5就是 2573 / 100 * 10 = 250個5,又因為7 > 5,所以 2550~2559,這裡還有10個沒算,於是就是 (2573 / 100 + 1)* 10,十位有260個5
對於百位來說,因為它前面有 2573 / 1000 = 2個,而且每個百位的5,會有500~599這100個,所以,百位的5就是 2573 / 1000 * 100 = 200個,又因5 == 5,所以對於2573來說,還有2500~2573這74個5,即(2573 / 1000 * 100) + (2573 % 100 + 1)
對於千位來說,它前面沒有值,即2573 / 10000 = 0。而且千位是2 < 5,所以千位沒有5
總共就是 257 + 260 + 274 個5,所以可以看出每一位即和前面有關係,又和後面有關係,前面有n個數,就是n * pow(10, 該位(個位是0,依次類推))。後面的話主要看該位數字是否大於想累計的數字,如果是就多加 1 * pow(10, 該位(個位是0,依次類推)),如果相等,就看該位後面有多少數,比如有m,就再加個(m+1),因為從0開始計數。如果小於,就不用做任何操作
下面程式碼中currentNumber表示1~n的整數中某個數字出現的次數,比如currentNumber=5,就是1~n中5出現的次數。
class Solution {
public:
int NumberOf1Between1AndN_Solution(int n)
{
int currentSum = 0;
int bitNum = 0;
int number = n;
int currentNumber = 1;
while (number > 0) {
int num = number % 10;
currentSum += (number / 10) * pow(10, bitNum);
if (num > currentNumber) {
currentSum += pow(10, bitNum);
}
else if (num == currentNumber) {
int temp = n % (int)pow(10, bitNum) + 1;
currentSum += temp;
}
number = number / 10;
bitNum++;
}
return currentSum;
}
};