剑指offer 32-从1到n整数中1出现的次数

来源:互联网 发布:mac优盘装win7 编辑:程序博客网 时间:2024/05/22 01:33

我们把从121345的所有数字分成两段,即1-13451346-21345

先来看1346-213451出现的次数。1的出现分为两种情况:一种情况是1出现在最高位(万位)。从121345的数字中,1出现在10000-1999910000个数字的万位中,一共出现了10000104)次;另外一种情况是1出现在除了最高位之外的其他位中。例子中1346-21345,这20000个数字中后面四位中1出现的次数是2000次(2*103,其中2是第一位的数值,103是因为数字的后四位数字其中一位为1,其余的三位数字可以在0910个数字任意选择,由排列组合可以得出总次数是2*103)。(这一段分析有点小问题,这20000个数字中后面四位中1出现的次数应该是8000次,2*4*10^3,其中2是第一位的数值,4是后面四位的位数长度,10^3是因为数字的后四位数字 其中一位为1,其余的三位数字可以在0到9这10个数字任意选择,由排列组合可以得出总次数是2*4*10^3,下面的代码实现,原作者写的是正确的)

至于从11345的所有数字中1出现的次数,我们就可以用递归地求得了。这也是我们为什么要把1-21345分为1-13451346-21345两段的原因。因为把21345的最高位去掉就得到1345,便于我们采用递归的思路。


#include<iostream>using namespace std;int PowerBase10(int N){int s=1;for(int i=0;i<N;i++)s=s*10;return s;}int NumberOf1(const char *strN){if(strN==NULL || *strN=='\0' ||*strN<'0' ||*strN>'9' )return 0;int first = *strN-'0';int length = strlen(strN); if(length == 1 && first == 0)        return 0;    if(length == 1 && first > 0)        return 1;// 假设strN是"21345"    // numFirstDigit是数字10000-19999的第一个位中1的数目int numFirstDigit = 0; if(first>1)numFirstDigit = PowerBase10(length-1);else if(first == 1)numFirstDigit = atoi(strN+1)+1;// numOtherDigits是01346-21345除了第一位之外的数位中1的数目int numOtherDigits = first*(length-1)*PowerBase10(length-2);// numRecursive是1-1345中1的数目    int numRecursive = NumberOf1(strN + 1);return numFirstDigit + numOtherDigits + numRecursive;}int NumberOf1Between1AndN(int n){if(n<=0)return 0;char strN[50];itoa(n,strN,10);return NumberOf1(strN);}// ====================测试代码====================void Test(char* testName, int n, int expected){    if(testName != NULL)        cout<<testName<<" ";        if(NumberOf1Between1AndN(n) == expected)        cout<<"passed."<<endl;    else        cout<<"failed."<<endl;   cout<<endl;  }void Test(){    Test("Test1", 1, 1);    Test("Test2", 5, 1);    Test("Test3", 10, 2);    Test("Test4", 55, 16);    Test("Test5", 99, 20);    Test("Test6", 10000, 4001);    Test("Test7", 21345, 18821);    Test("Test8", 0, 0);}int main(int argc, char* argv[]){    Test();    return 0;}


0 0