《剑指offer》第四十三题(从1到n整数中1出现的次数)
// 面试题43:从1到n整数中1出现的次数
// 题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。例如
// 输入12,从1到12这些整数中包含1 的数字有1,10,11和12,1一共出现了5次。 #include <iostream>
#include <cstring>
#include <cstdlib> // ====================方法一====================
//逐个判断,时间复杂度为O(nlogn),不好
int NumberOf1(unsigned int n); int NumberOf1Between1AndN_Solution1(unsigned int n)
{
int number = ; for (unsigned int i = ; i <= n; ++i)
number += NumberOf1(i); return number;
} int NumberOf1(unsigned int n)
{
int number = ;
while (n)
{
if (n % == )
number++; n = n / ;
} return number;
} // ====================方法二====================
int NumberOf1(const char* strN);
int PowerBase10(unsigned int n); int NumberOf1Between1AndN_Solution2(int n)//把数字换成字符串,方便处理
{
if (n <= )
return ; char strN[];
sprintf(strN, "%d", n);//格式化输出成字符串 return NumberOf1(strN);
} int NumberOf1(const char* strN)
{
if (!strN || *strN < '' || *strN > '' || *strN == '\0')
return ; int first = *strN - '';//第一位的最大值
unsigned int length = static_cast<unsigned int>(strlen(strN));//强制转换符 if (length == && first == )//边界特殊情况
return ; if (length == && first > )
return ; // 假设strN是"21345"
//先计算第一种情况,第一位为1的个数
// numFirstDigit是数字10000-19999的第一个位中1的数目
int numFirstDigit = ;
if (first > )
numFirstDigit = PowerBase10(length - );
else if (first == )
numFirstDigit = atoi(strN + ) + ;//若在1xx的情况,个数不到PowerBase10(length - 1),atoi是字符串转整数 //第二种情况,非第一位为1的个数
// numOtherDigits是01346-21345除了第一位之外的数位中1的数目
int numOtherDigits = first * (length - ) * PowerBase10(length - );//第一位可能性有first个,第二项表示选取除了第一位的任一位为1,剩下的有10种可能
// numRecursive是1-1345中1的数目,使用迭代处理
int numRecursive = NumberOf1(strN + ); return numFirstDigit + numOtherDigits + numRecursive;
} int PowerBase10(unsigned int n)//10的n次方
{
int result = ;
for (unsigned int i = ; i < n; ++i)
result *= ; return result;
} // ====================测试代码====================
void Test(const char* testName, int n, int expected)
{
if (testName != nullptr)
printf("%s begins: \n", testName); if (NumberOf1Between1AndN_Solution1(n) == expected)
printf("Solution1 passed.\n");
else
printf("Solution1 failed.\n"); if (NumberOf1Between1AndN_Solution2(n) == expected)
printf("Solution2 passed.\n");
else
printf("Solution2 failed.\n"); printf("\n");
} void Test()
{
Test("Test1", , );
Test("Test2", , );
Test("Test3", , );
Test("Test4", , );
Test("Test5", , );
Test("Test6", , );
Test("Test7", , );
Test("Test8", , );
} int main(int argc, char* argv[])
{
Test();
system("pause");
return ;
}
《剑指offer》第四十三题(从1到n整数中1出现的次数)的更多相关文章
- 《剑指offer》第十三题(机器人的运动范围)
// 面试题:机器人的运动范围 // 题目:地上有一个m行n列的方格.一个机器人从坐标(0, 0)的格子开始移动,它 // 每一次可以向左.右.上.下移动一格,但不能进入行坐标和列坐标的数位之和 // ...
- 《剑指offer》第二十三题(链表中环的入口结点)
// 面试题23:链表中环的入口结点 // 题目:一个链表中包含环,如何找出环的入口结点?例如,在图3.8的链表中, // 环的入口结点是结点3. #include <iostream> ...
- 剑指offer第四章
剑指offer第四章 1.二叉树的镜像 二叉树的镜像:输入一个二叉树,输出它的镜像 分析:求树的镜像过程其实就是在遍历树的同时,交换非叶结点的左右子结点. 求镜像的过程:先前序遍历这棵树的每个结点,如 ...
- 剑指Offer(三十三):丑数
剑指Offer(三十三):丑数 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/baidu_31 ...
- 剑指Offer(二十三):二叉搜索树的后序遍历序列
剑指Offer(二十三):二叉搜索树的后序遍历序列 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.ne ...
- 剑指Offer(三十七):数字在排序数组中出现的次数
剑指Offer(三十七):数字在排序数组中出现的次数 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.n ...
- JS 剑指Offer(四) 从尾到头打印链表
题目:输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回). 首先定义一下链表中的节点,关于链表这个数据结构在另外一篇文章中会详细讲 function ListNode(val) { t ...
- 【剑指Offer面试编程题】题目1373:整数中1出现的次数--九度OJ
题目描述: 亲们!!我们的外国友人YZ这几天总是睡不好,初中奥数里有一个题目一直困扰着他,特此他向JOBDU发来求助信,希望亲们能帮帮他.问题是:求出1~13的整数中1出现的次数,并算出100~130 ...
- 【剑指Offer学习】【面试题:二维数组中的查找】PHP实现
最近一直看剑指Offer.里面很多算法题.于是就想着用PHP来显示一下. 题目: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序. 请完成一个函数,输入这样的 ...
- 《剑指offer》写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
弱菜刷题还是刷中文题好了,没必要和英文过不去,现在的重点是基本代码能力的恢复. [题目] 剑指offer 写一个函数,求两个整数之和,要求在函数体内不得使用+.-.*./四则运算符号. [思路] 直觉 ...
随机推荐
- P4316 绿豆蛙的归宿(期望)
P4316 绿豆蛙的归宿 因为非要用bfs所以稍微麻烦一点qwq(大家用的都是dfs) 其实问题让我们求的就是经过每条边的概率*边权之和 我们可以用bfs把图遍历一遍处理概率,顺便把每条边的概率*边权 ...
- ORA-12052: cannot fast refresh materialized view
SQL> execute dbms_mview.refresh ('TX_FAIL_LOG_DAY_MV', 'f'); BEGIN DBMS_MVIEW.REFRESH ('TX_FAIL_L ...
- Linux 编程简单示例代码
Linux进程管理 编辑a.c 文件 #include <stdio.h> #include <unistd.h> int main() { printf( "Mes ...
- entry points
https://amir.rachum.com/blog/2017/07/28/python-entry-points/
- matlab做聚类分析
说明:如果是要用matlab做kmeans聚类分析,直接使用函数kmeans即可.使用方法:kmeans(输入矩阵,分类个数k). 转载一: MATLAB提供了两种方法进行聚类分析: 1.利用 clu ...
- LightOJ 1030 Discovering Gold(概率DP)题解
题意:1~n每格都有金子,每次掷骰子,掷到多少走几步,拿走那格的金子,问你金子的期望 思路:dp[i]表示从i走到n金子的期望,因为每次最多走1<=x<=6步,所以dp[i] = a[i] ...
- 【原理、应用】Quartz集群原理及配置应用
一.Quartz任务调度的基本实现原理 Quartz是OpenSymphony开源组织在任务调度领域的一个开源项目,完全基于Java实现.作为一个优秀的开源调度框架,Quartz具有以下特点: 强大的 ...
- BZOJ4893: 项链分赃 && BZOJ4895: 项链分赃(增强版)
Solution 神仙题.jpg 切一刀简单啊,维护一个前缀和. 切两刀简单啊,拿个队列维护中间那一段. 切三刀,这tm什么毒瘤题. 于是打开题解:"保证不会答案不会超过宝石种类" ...
- [CodeForce 801A] Vicious Keyboard
题目链接:http://codeforces.com/problemset/problem/801/A 思路:题目中字符串的长度最长100个字符,所以,可以考虑用暴力,先遍历一遍匹配"VK& ...
- vue.js精讲01
笔记及源码地址 : https://github.com/wll8/vue_note 01 2017-09-13 view一个 mvvm框架(库),和 ag 类似.比较小巧,容易上手. mvc: mv ...