剑指Offer(三十一):整数中1出现的次数(从1到n整数中1出现的次数)
剑指Offer(三十一):整数中1出现的次数(从1到n整数中1出现的次数)
搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法、机器学习干货
csdn:https://blog.csdn.net/baidu_31657889/
github:https://github.com/aimi-cn/AILearners
一、引子
这个系列是我在牛客网上刷《剑指Offer》的刷题笔记,旨在提升下自己的算法能力。
查看完整的剑指Offer算法题解析请点击CSDN和github链接:
剑指Offer完整习题解析CSDN地址
github地址
二、题目
求出113的整数中1出现的次数,并算出11300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现5次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。
1、思路
方法1:最直观的是,对于1~n中的每个整数,分别判断n中的1的个数,具体见《剑指offer》。这种方法的时间复杂度为O(N*logN),当N比较大的时候,一般会超时。
方法2:这种类别的题目,如果直观求解不行的话,那么通常是进行找规律,转化成一个数学问题。这道题目在《编程之美》上有着比较详细的描述,下面就结合一个实例进行具体的分析:
在分析之前,首先需要知道一个规律:
- 从 1 至 10,在它们的个位数中,数字1出现了 1 次。
- 从 1 至 100,在它们的十位数中,数字1出现了 10 次。
- 从 1 至 1000,在它们的百位数中,数字1出现了 100 次。
依此类推,从 1 至 10i,在它们右数第二位中,数字1出现了10 ^ (i - 1)次。
对于 n = 2134,要找到从1 ~ 2134这2134个数字中所有1的个数。我们可以对2134进行逐位分析:
(1)在个位上,从1~2130,包含213个10,因此数字1出现了213次,剩下的数字2131、2132、2133、2134中个位数上只有2131包含树脂字1,剩下的都不包含。所以个位数上的数字1的总数为213 + 1 = 214。
(2)在十位上,从1 ~ 2100,包含了21个100,因此数字1出现了21 * 10 = 210次,剩下的数字从2101 ~ 2134,只有2110 ~ 2119这10个数字中十位的数字为1,所以十位上的数字1的总数为210 + 10 = 220。
(3)在百位上,从1 ~ 2000,包含了2个1000,因此数字1出现了2 * 100 = 200次,剩下的数字从2001 ~ 2134,只有2100 ~ 2134这35个数字中的百位的数字为1,所以百位数上数字1的总数为200 + 35= 235。
(4)在千位上,包含了0个10000,因此数字1出现了0 * 1000 = 0次,剩下的数字中只有1000 ~ 1999这1000个数字中的千位的数字为1,所以千位上的数字1的总数为1000。
因此从1 ~ 2134这n个数字中,数字出现的总的次数为 214 + 220 + 235 +1000 = 1669。
总结一下以上的步骤,可以得到这么一个规律:
对于数字n,计算它的第i(i从1开始,从右边开始计数)位数上包含的数字1的个数:
假设第i位上的数字为x的话,则
1.如果x > 1的话,则第i位数上包含的1的数目为:(高位数字 + 1)* 10 ^ (i-1) (其中高位数字是从i+1位一直到最高位数构成的数字)
2.如果x < 1的话,则第i位数上包含的1的数目为:(高位数字 )* 10 ^ (i-1)
3.如果x == 1的话,则第i位数上包含1的数目为:(高位数字) * 10 ^ (i-1) +(低位数字+1) (其中低位数字时从第i - 1位数一直到第1位数构成的数字)
2、编程实现
python
代码实现方案:
# -*- coding:utf-8 -*-
class Solution:
def NumberOf1Between1AndN_Solution(self, n):
# write code here
if n < 1:
return 0
# mult位数 sumTime出现1的次数和
mult, sumTimes = 1, 0
while n//mult:
div, mod = divmod(n, mult*10)
curNum, curMod = divmod(mod, mult)
if curNum > 1:
sumTimes += div*mult + mult
elif curNum == 1:
sumTimes += div*mult + curMod + 1
else:
sumTimes += div*mult
mult = mult*10
return sumTimes
AIMI-CN AI学习交流群【1015286623】 获取更多AI资料
分享技术,乐享生活:我们的公众号计算机视觉这件小事每周推送“AI”系列资讯类文章,欢迎您的关注!
剑指Offer(三十一):整数中1出现的次数(从1到n整数中1出现的次数)的更多相关文章
- 剑指offer三十一之连数中1出现的次数(从1到n整数中1出现的次数
一.题目 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙了. ...
- 剑指offer三十五之数组中的逆序对
一.题目 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%1000 ...
- 剑指Offer(三):从尾到头打印链表
说明: 1.本系列是根据<剑指Offer>这个系列做的一个小笔记. 2.直接动力是因为师兄师姐找工作很难,而且机械出生的我面试算法更难. 3.刚开始准备刷LeetCode.LintCode ...
- 剑指offer五十一之构建乘积数组
一.题目 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1].不 ...
- 《剑指Offer》第1题(Java实现):在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
一.题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该 ...
- 剑指offer三十七之数字在排序数组中出现的次数
一.题目 统计一个数字在排序数组中出现的次数. 二.思路 解法一:遍历数组计数 解法二:考虑到时有序数组,所以采用分查找,找到第一个K 和 最后一个K的位置, 二者相减. 三.代码 解法一: publ ...
- 剑指offer 第十一天
46.扑克牌顺子 LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的 ...
- 剑指offer二十一之栈的压入、弹出序列
一.题目 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序 ...
- 算法学习之剑指offer(十一)
一 题目描述 请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推. import java.util.*; ...
- C++版 - 剑指offer 面试题63:二叉搜索树的第k个结点(二叉树中序遍历的应用) 题解
面试题 63:二叉搜索树的第k个结点 题目:给定一颗二叉搜索树,请找出其中的第k大的结点.例如, 5 / \ 3 7 /\ /\ 2 4 6 8 (见下面的图1) 中,按结点数值大小顺序第三个结点的值 ...
随机推荐
- @media 适配兼容
/* 兼容iphone4/4s */ @media (device-height:480px) and (-webkit-min-device-pixel-ratio:2){ } /* 兼容iphon ...
- 【bcrypt】vue项目中bcrypt安装报错
[报错] 报错时安装方法: npm install bcrypt [解决方法] npm install bcryptjs 用 bcryptjs 替换 bcrypt 即可.
- [C++] 非递归实现前中后序遍历二叉树
目录 前置技能 需求描述 binarytree.h 具体实现 binarytree.cpp main.cpp 网上代码一搜一大片,大同小异咯. 书上的函数实现代码甚至更胜一筹,而且抄一遍就能用,唯一问 ...
- 虚拟环境搭建Django项目
下载虚拟环境包 pip install virtualenv 创建虚拟环境 virtualenv env 进入env文件夹 cd env 进入Scripts文件夹 cd Scripts 启动虚拟环 ...
- WUSTOJ 1344: still水题(Java)进制转换
题目链接:1344: still水题 Description 送AC,不解释 Input 输入两个整数n和b,b表示该数的进制(包含2.8.16进制,多组数组) Output 输出该整数(10进制,每 ...
- 【计数DP】种树
种树 题目描述 事实上,小X邀请两位奆老来的目的远不止是玩斗地主,主要是为了抓来苦力,替他的后花园种树……小X的后花园是环形的,他想在花园周围均匀地种上n棵树,但是奆老花园的土壤当然非同寻常,每个位置 ...
- SQLSERVER 根据值查询表名
CREATE PROCEDURE [dbo].[SP_FindValueInDB](@value VARCHAR(1024)) ASBEGIN-- SET NOCOUNT ON added to pr ...
- 撸一个 vue 的截图组件,按比例截取
<template> <div class="clip-img" :style="imgStyle"> <img :src=&qu ...
- Android GridView去除自带边框点击效果、去除右侧滚动条、禁止上下滑动
一.去除自带边框点击效果: <com.example.gridview.MyGridView android:id="@+id/grid_upload_pictures" a ...
- hdu 5432
Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he ...