剑指Offer----面试题32:从1到n整数中1出现的次数
来源:互联网 发布:安卓 windows 如何切换 编辑:程序博客网 时间:2024/06/05 15:36
题目:
输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。例如输入12,从1到12这些整数中包含1的数字有1,10,11,12,也就是说1出现了5次。
方法一:不考虑时间复杂度的解法
分析:
循环遍历从1到n的每一个数字,累加每一个数字中所包含的1的个数,如果输入数字n,n有O(logn)位,那么时间复杂度就是O(n*longn)。
源代码实现:
#include<iostream>using namespace std;int ComputeNum1(int num){int Cnum = 0;for (int i = 1; i <= num; ++i){int temp = i;while (temp){int yushu = temp % 10;if (yushu == 1)++Cnum;temp /= 10;}}return Cnum;}void test1(){cout << "===============test1:输入边界值0==============" << endl;cout << ComputeNum1(0) << endl;cout << endl;}void test2(){cout << "===============test2:输入边界值1==============" << endl;cout << ComputeNum1(1) << endl;cout << endl;}void test3(){cout << "===============test3:输入负值-12==============" << endl;cout << ComputeNum1(-12) << endl;cout << endl;}void test4(){cout << "===============test4:输入正常值12==============" << endl;cout << ComputeNum1(12) << endl;cout << endl;}int main(){test1();test2();test3();test4();system("pause");return 0;}
===============test1:输入边界值0==============0===============test2:输入边界值1==============1===============test3:输入负值-12==============0===============test4:输入正常值12==============5请按任意键继续. . .
方法二:从数字规律着手
分析:
例如输入数字21345,我们将之分为两段1~1345和1346~21345。
首先看1346~21345中1出现的次数。这时候又分为两种情况:
- 首先是1出现在最高位(万位)的情况,10000~19999,共出现了10000次,这时需要注意的是,并不是对所有的5位数而言在万位出现的次数都是10000次,对于万位是1的数字如12345,1出现在万位的次数是2346次,也就是出去最高位的数字加上1;
- 其次是1出现在最高位之外的其他四位数中的情况。例子中1345~21345中数字中后4为中1出现的次数是2000次。由于最高位为2,可以再分为两段1346~11325和11346~21345,每一段剩下的4位数字中,选择其中一位为1,其他三位从十位数字中随机选择,相当于全排列,因此有2*10*10*10 = 2000次。
其次是1~1345,使用递归的思路。
源代码:
#define _CRT_SECURE_NO_WARNINGS#include<iostream>#include<cstdio>using namespace std;int NumberOf1(const char *strN);int PowerBase10(unsigned int n);int NumberOf1Between1AndN(int n){if (n <= 0)return 0;char strN[50];sprintf(strN, "%d", n);return NumberOf1(strN);}int NumberOf1(const char *strN){if (strN == nullptr || *strN<'0' || *strN>'9' || *strN == '\0')return 0;int first = *strN - '0';unsigned int length = static_cast<unsigned int>(strlen(strN));if (length == 1 && first == 0)return 0;if (length == 1 && first > 0)return 1;//假设strN是“21345”//numFirstDigit是数字10000~19999的第一个位中的数目int numFirstDigit = 0;if (first > 1)numFirstDigit = PowerBase10(length - 1);else if (first == 1)numFirstDigit = atoi(strN + 1) + 1;//numOtherDigits是1346~21345除了第一位之外的数位中的数目int numOtherDigits = first*(length - 1)*PowerBase10(length - 2);//numberRecursive是1~1345中的数目int numRecursive = NumberOf1(strN + 1);return numFirstDigit + numOtherDigits + numRecursive;}int PowerBase10(unsigned int n){int result = 1;for (unsigned int i = 0; i < n; ++i)result *= 10;return result;}void test11(){cout << "===============test1:输入边界值0==============" << endl;cout << NumberOf1Between1AndN(0) << endl;cout << endl;}void test12(){cout << "===============test2:输入边界值1==============" << endl;cout << NumberOf1Between1AndN(1) << endl;cout << endl;}void test13(){cout << "===============test3:输入负值-12==============" << endl;cout << NumberOf1Between1AndN(-12) << endl;cout << endl;}void test14(){cout << "===============test4:输入正常值12==============" << endl;cout << NumberOf1Between1AndN(21345) << endl;cout << endl;}int main(){test11();test12();test13();test14();system("pause");return 0;}
===============test1:输入边界值0==============0===============test2:输入边界值1==============1===============test3:输入负值-12==============0===============test4:输入正常值21345==============18821请按任意键继续. . .
0 0
- [剑指offer][面试题32]从1到n整数中1出现的次数
- 剑指Offer:面试题32 从1到n整数中1出现的次数
- 剑指offer 面试题32—从1到n整数中1出现的次数
- 剑指offer-面试题32:从1到n整数中1出现的次数
- 算法 剑指Offer 面试题32 从1到n整数中1出现的次数
- 剑指Offer----面试题32:从1到n整数中1出现的次数
- 剑指offer面试题 32:从 1 到 n 整数中 1 出现的次数
- 剑指offer面试题32:从1到n整数中1出现的次数
- 【剑指offer】面试题32-从1到n整数中1出现的次数
- 剑指Offer系列-面试题32:从1到n整数中1出现的次数
- 剑指offer 面试题32 从 1 到 n 整数中 1 出现的次数
- 剑指offer-面试题32-从1到n整数中1出现的次数
- 剑指offer面试题[32]:从1到n整数中1出现的次数
- 【剑指Offer】面试题32:从1到n整数中1出现的次数
- 剑指Offer:面试题32:从1到n整数中1出现的次数
- 剑指offer-面试题32.从1到n整数中1出现的次数
- 剑指offer面试题 求从1到n整数中1出现的次数
- 剑指Offer之面试题32:从1到N整数1出现的次数
- WPF:绑定到非元素对象
- Node.js V6.2在Windows 64位环境下的安装
- mybatis的二级缓存和hibernate的三级缓存
- VS2015 VC报错 error LNK2019
- Android Volley完全解析
- 剑指Offer----面试题32:从1到n整数中1出现的次数
- php应用程序效率监测 xhprof
- 起泡排序(冒泡排序)
- 解决cocos2dx 3.12版本使用PageView调用addEventListener函数,参数不明问题
- java程序向mysql数据库插入数据中文 乱码问题解决
- 设备树
- 字符串单词反转
- SDUT2134数据结构实验之栈四:括号匹配(栈)
- 数据库存储全方案,详解持久化技术