求出任意非负整数区间中1出现的次数

简介: 求出任意非负整数区间中1出现的次数

引言


最近想中有一个 类似标题的需求,看到需求的时候觉得非常简单,立马闪现出下面代码思路:

 public static int couts(int n) {
        int cout = 0;
        for (int i = 1; i <= n; i++) {
            String s = String.valueOf(i);
            String replace = s.replace("1", "");
            int i1 = s.length() - replace.length();
            cout = cout + i1;
        }
        return cout;
    }

多么简单,就是这么简单。写出来以后,稍微一过脑子,觉得不行,时间复杂度太高。所以,我们需要分析一下数据。


首先分析规律

F(3)=1
F(13)=2+4=6
F(19)=2+10=12
F(23)=3+10
F(33)=4+10
F(93)=10+10=20
F(123)=24+20+13=57


设N = abcde ,其中abcde分别为十进制中各位上的数字。


如果要计算百位上1出现的次数,它要受到3方面的影响:百位上的数字,百位一下(低位)上的数字,百位一上(高位)上的数字。


如果百位上数字为0,百位上可能出现1的次数由更高位决定。比 如:12013,则可以知道百位出现1的情况可能 是:100~199,1100~1199,2100~2199,,.........,11100~11199,一共1200个。可以看出是由更高位数字 (12)决定,并且等于更高位数字(12)乘以 当前位数(100)。


如果百位上数字为1,百位上可能出现1的次数不仅受更高位影响还受低 位影响。比如:12113,则可以知道百位受高位影响出现的情况 是:100~199,1100~1199,2100~2199,,.........,11100~11199,一共1200个。和上面情况一样,并且等 于更高位数字(12)乘以 当前位数(100)。但同时它还受低位影响,百位出现1的情况是:12100~12113,一共14个,等于低位数字(13)+1。


如果百位上数字大于1(2~9),则百位上出现1的情况仅由更高位决 定,比如12213,则百位出现1的情况 是:100~199,1100~1199,2100~2199,...........,11100~11199,12100~12199,一共有 1300个,并且等于更高位数字+1(12+1)乘以当前位数(100)。


所以代码如下:

 public static int oneCount(int n) {
        int count = 0;//1的个数
        int i = 1;//当前位
        int current = 0, after = 0, before = 0;
        while ((n / i) != 0) {
            //当前位数值
            current = (n / i) % 10;
            //高位数值
            before = n / (i * 10);
            //低位数值
            after = n - (n / i) * i; 
            //如果为0,出现1的次数由高位决定,等于高位数字 * 当前位数
            if (current == 0)
                count += before * i;
                //如果为1,出现1的次数由高位和低位决定,高位*当前位+低位+1
            else if (current == 1)
                count += before * i + after + 1;
                //如果大于1,出现1的次数由高位决定,//(高位数字+1)* 当前位数
            else {
                count += (before + 1) * i;
            }
            //前移一位
            i = i * 10;
        }
        return count;
    }

测试运行,时间耗费立马减少了很多。

目录
相关文章
|
11月前
|
架构师 关系型数据库 MySQL
MySQL最左前缀优化原则:深入解析与实战应用
【10月更文挑战第12天】在数据库架构设计与优化中,索引的使用是提升查询性能的关键手段之一。其中,MySQL的最左前缀优化原则(Leftmost Prefix Principle)是复合索引(Composite Index)应用中的核心策略。作为资深架构师,深入理解并掌握这一原则,对于平衡数据库性能与维护成本至关重要。本文将详细解读最左前缀优化原则的功能特点、业务场景、优缺点、底层原理,并通过Java示例展示其实现方式。
375 1
|
11月前
|
网络协议 Java 应用服务中间件
Tomcat中的WebSocket是如何实现的?
【10月更文挑战第7天】本文介绍了WebSocket在Tomcat中的实现,包括其全双工通信、单个TCP连接、协议升级和事件驱动的特点。通过Spring Boot项目整合WebSocket,展示了如何配置依赖、创建WebSocket处理类和配置类。详细解析了WebSocket的原理,包括ServerEndpointExporter的注册过程和请求处理流程。总结了WebSocket与HTTP请求处理的区别,并提供了进一步学习的资源。
Tomcat中的WebSocket是如何实现的?
|
数据采集 搜索推荐 算法
Python基于协同过滤算法进行电子商务网站用户行为分析及服务智能推荐
Python基于协同过滤算法进行电子商务网站用户行为分析及服务智能推荐
|
11月前
|
存储 C语言
C 标准库 - <stdlib.h>详解
`&lt;stdlib.h&gt;` 是 C 语言标准库中的头文件,提供了多种工具和函数,涵盖内存管理、进程控制、转换及随机数生成等功能。其中包括 `malloc`、`calloc` 和 `free` 等内存管理函数,`atoi` 和 `atof` 等转换函数,以及 `rand` 和 `srand` 等随机数生成函数。此外,还提供了 `exit` 和 `atexit` 等程序控制函数,以及 `getenv` 和 `system` 等环境控制函数。
1031 11
|
12月前
|
监控 物联网 数据安全/隐私保护
智能家居包含了众多设备,在通过智能化技术提升居家生活的便利性、安全性、节能性和舒适度
智能家居系统包含了众多设备,旨在通过智能化技术提升居家生活的便利性、安全性、节能性和舒适度。以下是一些智能家居系统中常见的设备类别及其基本操作简述:
|
关系型数据库 MySQL 网络安全
VPS搭建WordPress
如果你想搭建的WordPress拥有一个较好的性能的话,那么你可以选择在VPS上搭建WordPress。本文将会带你从零开始,在VPS上一步一步敲代码来搭建WordPress。首先,你需要注册一台VPS,登录你的VPS先搭建好LAMP环境;接下来你需要将你的域名已经解析到你的VPS。在域名解析成功后,你需要创建MySQL数据库,然后安装PHP插件并配置Apache,接下来下载并配置WordPress,最后是安装SSL证书。
480 1
VPS搭建WordPress
|
机器学习/深度学习 人工智能 API
百度飞桨(PaddlePaddle)- 张量(Tensor)
百度飞桨(PaddlePaddle)- 张量(Tensor)
207 3
百度飞桨(PaddlePaddle)- 张量(Tensor)
GitHub——README.md挂件如何生成
使用`shields.io`即可生成github的markdown的挂件
119 0
GitHub——README.md挂件如何生成
|
设计模式 算法 编译器
【C++ 泛型编程 入门篇】C++ 元编程 :模板结构体的的使用教程
【C++ 泛型编程 入门篇】C++ 元编程 :模板结构体的的使用教程
543 1
|
Java Spring 容器
深入理解@EnableAspectJAutoProxy的力量
深入理解@EnableAspectJAutoProxy的力量
627 0