// 面试题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出现的次数)的更多相关文章

  1. 《剑指offer》第十三题(机器人的运动范围)

    // 面试题:机器人的运动范围 // 题目:地上有一个m行n列的方格.一个机器人从坐标(0, 0)的格子开始移动,它 // 每一次可以向左.右.上.下移动一格,但不能进入行坐标和列坐标的数位之和 // ...

  2. 《剑指offer》第二十三题(链表中环的入口结点)

    // 面试题23:链表中环的入口结点 // 题目:一个链表中包含环,如何找出环的入口结点?例如,在图3.8的链表中, // 环的入口结点是结点3. #include <iostream> ...

  3. 剑指offer第四章

    剑指offer第四章 1.二叉树的镜像 二叉树的镜像:输入一个二叉树,输出它的镜像 分析:求树的镜像过程其实就是在遍历树的同时,交换非叶结点的左右子结点. 求镜像的过程:先前序遍历这棵树的每个结点,如 ...

  4. 剑指Offer(三十三):丑数

    剑指Offer(三十三):丑数 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/baidu_31 ...

  5. 剑指Offer(二十三):二叉搜索树的后序遍历序列

    剑指Offer(二十三):二叉搜索树的后序遍历序列 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.ne ...

  6. 剑指Offer(三十七):数字在排序数组中出现的次数

    剑指Offer(三十七):数字在排序数组中出现的次数 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.n ...

  7. JS 剑指Offer(四) 从尾到头打印链表

    题目:输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回). 首先定义一下链表中的节点,关于链表这个数据结构在另外一篇文章中会详细讲 function ListNode(val) { t ...

  8. 【剑指Offer面试编程题】题目1373:整数中1出现的次数--九度OJ

    题目描述: 亲们!!我们的外国友人YZ这几天总是睡不好,初中奥数里有一个题目一直困扰着他,特此他向JOBDU发来求助信,希望亲们能帮帮他.问题是:求出1~13的整数中1出现的次数,并算出100~130 ...

  9. 【剑指Offer学习】【面试题:二维数组中的查找】PHP实现

    最近一直看剑指Offer.里面很多算法题.于是就想着用PHP来显示一下. 题目: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序. 请完成一个函数,输入这样的 ...

  10. 《剑指offer》写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

    弱菜刷题还是刷中文题好了,没必要和英文过不去,现在的重点是基本代码能力的恢复. [题目] 剑指offer 写一个函数,求两个整数之和,要求在函数体内不得使用+.-.*./四则运算符号. [思路] 直觉 ...

随机推荐

  1. scrapy selenium 登陆zhihu

    # -*- coding: utf-8 -*- # 导入依赖包 import scrapy from selenium import webdriver import time import json ...

  2. Scrapy学习笔记(5)-CrawlSpider+sqlalchemy实战

    基础知识 class scrapy.spiders.CrawlSpider 这是抓取一般网页最常用的类,除了从Spider继承过来的属性外,其提供了一个新的属性rules,它提供了一种简单的机制,能够 ...

  3. python3 获取cookie解决方案

    python3 获取cookie解决方案 方案一: 利用selenium+phantomjs无界面浏览器的形式访问网站,再获取cookie值: from selenium import webdriv ...

  4. 【题解】Luogu P2604 [ZJOI2010]网络扩容

    原题传送门:P2604 [ZJOI2010]网络扩容 这题可以说是板题 给你一个图,先让你求最大流 再告诉你,每条边可以花费一些代价,使得流量加一 问至少花费多少代价才能使最大流达到k 解法十分简单 ...

  5. python简说(二十六)异常

    # try:# res = 1 / 0# except ZeroDivisionError as e:# print('出错啦,除数不能为0',e) # l = list()# l.append(1) ...

  6. 如何将QT的pro图标修改的更显著一些

    如何将QT的pro图标修改的更显著一些 QT的项目打开文件是pro,默认是这样的 这个白色的背景在很多文件中很不好找 所以使用工具进行相关修改. 寻找到.pro 双击修改ico 默认的这个就非常不错. ...

  7. Python3 tkinter基础 Label 显示的文字换行

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  8. selinux权限问题【转】

    本文转载自:https://blog.csdn.net/u011386173/article/details/83339770 版权声明:本文为博主原创文章,未经博主允许不得转载. https://b ...

  9. sql 之 INSERT IGNORE

    INSERT IGNORE 与INSERT INTO的区别就是INSERT IGNORE会忽略数据库中已经存在 的数据,如果数据库没有数据,就插入新的数据,如果有数据的话就跳过这条数据.这样就可以保留 ...

  10. P2536 [AHOI2005]病毒检测

    反思 对于*符号,明明可以让相同位置再次匹配下一个,或者跳过当前位置匹配,但是却写了个把trie的子树全部push进队列的垃圾写法,结果一直MLE 告辞 思路 模板串多且不长,可以塞到trie树里,这 ...