C++二分查找算法:最大为 N 的数字组合

涉及知识点

二分查找 数学

题目

给定一个按 非递减顺序 排列的数字数组 digits 。你可以用任意次数 digits[i] 来写的数字。例如,如果 digits = [‘1’,‘3’,‘5’],我们可以写数字,如 ‘13’, ‘551’, 和 ‘1351315’。
返回 可以生成的小于或等于给定整数 n 的正整数的个数 。
示例 1:
输入:digits = [“1”,“3”,“5”,“7”], n = 100
输出:20
解释:
可写出的 20 个数字是:
1, 3, 5, 7, 11, 13, 15, 17, 31, 33, 35, 37, 51, 53, 55, 57, 71, 73, 75, 77.
示例 2:
输入:digits = [“1”,“4”,“9”], n = 1000000000
输出:29523
解释:
我们可以写 3 个一位数字,9 个两位数字,27 个三位数字,
81 个四位数字,243 个五位数字,729 个六位数字,
2187 个七位数字,6561 个八位数字和 19683 个九位数字。
总共,可以使用D中的数字写出 29523 个整数。
示例 3:
输入:digits = [“7”], n = 8
输出:1
参数范围
1 <= digits.length <= 9
digits[i].length == 1
digits[i] 是从 ‘1’ 到 ‘9’ 的数
digits 中的所有值都 不同
digits 按 非递减顺序 排列
1 <= n <= 109

分析

假定n是m位数,digits.length的长度是k。
[1,m)位数显然都小于n。x位数都可以任意选择,所以可能是pow(k,x)。
x大于m,显然大于n,直接淘汰。
x等于m,则要分情况讨论。

最高位的数小于n的最高位
最高位的数等于n的最高位,次高位小于n的次高位
最高位、次高位等于n,第三高位小于n的第三高位
高位和n的高位相等,个位小于n
和n相等

注意

和n相等的数不一定存在。
digits[i]没重复数据,没有0,已经按升序排序。

代码

核心代码

class Solution {
public:
int atMostNGivenDigitSet(vector& digits, int n) {
vector vValues;
for (const auto& s : digits)
{
vValues.emplace_back(s[0] - ‘0’);
}
string strN = std::to_string(n);
int iRet = 0;
//假定n是m位数,那么[1,m)位一定符合
int iCur = vValues.size();
for (int i = 1; i < strN.length(); i++)
{
iRet += iCur;
iCur *= vValues.size();
}
iCur /= vValues.size();
for (int i = 0; i < strN.length(); i++)
{
const int iLessNum = std::lower_bound(vValues.begin(), vValues.end(), strN[i]-‘0’) - vValues.begin();
const int iLessEqualNum = std::upper_bound(vValues.begin(), vValues.end(), strN[i] - ‘0’) - vValues.begin();
iRet += iCur * iLessNum;//从左到右第i位小于n的数的数量
if (iLessNum == iLessEqualNum)
{
break;
}
iCur /= vValues.size();
if (i + 1 == strN.length())
{
iRet++;//完全相等
}
}
return iRet;
}

};

测试用例

template
void Assert(const T& t1, const T& t2)
{
assert(t1 == t2);
}

template
void Assert(const vector& v1, const vector& v2)
{
if (v1.size() != v2.size())
{
assert(false);
return;
}
for (int i = 0; i < v1.size(); i++)
{
Assert(v1[i], v2[i]);
}
}

int main()
{
vector digits;
int n;
int res;
{
digits = { “1”, “3”, “5”, “7” };
int n = 100;
res = Solution().atMostNGivenDigitSet(digits,n);
Assert(20, res);
}
{
digits = { “1”, “4”, “9” };
int n = 1000000000;
res = Solution().atMostNGivenDigitSet(digits, n);
Assert(29523, res);
}
{
digits = { “7” };
int n = 8;
res = Solution().atMostNGivenDigitSet(digits, n);
Assert(1, res);
}

//CConsole::Out(res);

}

2023年8月代码

class Solution {
public:
int atMostNGivenDigitSet(vector& digits, int n) {
int iBitNum = 0;
int tmp = n;
while (tmp > 0)
{
iBitNum++;
tmp /= 10;
}
std::set nums;
for (const auto& s : digits)
{
nums.insert(s[0] - ‘0’);
}
int iMul = 1;
int iMul10 = 1;
int iResultNum = 0;
for (int i = 0; i+1 < iBitNum; i++)
{
iMul *= nums.size();
iResultNum += iMul;
iMul10 = 10;
}
for (int i = 0; i < iBitNum; i++)
{
int iCurBitNum = n / iMul10%10;
auto it = nums.equal_range(iCurBitNum);
iResultNum += iMul
std::distance(nums.begin(), it.first);
if ( it.first == it.second )
{
break;
}
else
{
if (iBitNum-1 == i)
{
iResultNum++;
}
}
iMul10 /= 10;
iMul /= nums.size();
}
return iResultNum;
}
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《闻缺陷则喜算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

洒家想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
墨家名称的来源:有所得以墨记之。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境:

VS2022 C++17

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/146975.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Activiti工作流学习笔记(四)——工作流引擎中责任链模式的建立与应用原理

原创/朱季谦 本文需要一定责任链模式的基础与Activiti工作流知识&#xff0c;主要分成三部分讲解&#xff1a; 一、简单理解责任链模式概念二、Activiti工作流里责任链模式的建立三、Activiti工作流里责任链模式的应用 一、简单理解责任链模式概念 网上关于责任链模式的介绍…

科技驱动固定资产管理变革:RFID技术的前沿应用

在当今激烈竞争的商业环境中&#xff0c;企业固定资产管理面临挑战&#xff0c;而RFID技术正以其独特特性和功能性彻底改变资产管理方式。本文将深入探讨RFID技术在固定资产管理中的革命性作用&#xff0c;并解析其应用带来的创新和便利。 RFID技术概述&#xff1a; RFID系统作…

C/C++轻量级并发TCP服务器框架Zinx-框架开发002: 定义通道抽象类

文章目录 2 类图设计3 时序图数据输入处理&#xff1a;输出数据处理总流程 4 主要实现的功能4.1 kernel类&#xff1a;基于epoll调度所有通道4.2 通道抽象类&#xff1a;4.3 标准输入通道子类4.4 标准输出通道子类4.5 kernel和通道类的调用 5 代码设计5.1 框架头文件5.2 框架实…

20.2 设备树中的 platform 驱动编写

一、设备树下的 platform 驱动 platform 驱动框架分为总线、设备和驱动&#xff0c;总线不需要我们去管理&#xff0c;这个是 Linux 内核提供。在有了设备树的前提下&#xff0c;我们只需要实现 platform_driver 即可。 1. 修改 pinctrl-stm32.c 文件 先复习一下 pinctrl 子系…

从申请服务器到Docker部署Java项目至最后运行完结

目录 1.申请服务器篇 2.配置安全组篇 3.Docker安装篇 4.代码编写打包篇 目录结构 Maven Controller DockerFile 开始打包 5.所需文件上传及镜像构建篇 上传准备 上传jar包及DockerFile文件 指令构建 验证 6.镜像启动服务验证篇 启动镜像 使用云服务器地址进行…

一文讲清生产质量场景的数据分析思路及案例实战

今天&#xff0c;顺着制造业数据分析这个大主题&#xff0c;我们来讲讲质量管理数据分析。   说起质量管理&#xff0c;就是对所生产的产品质量进行管理&#xff0c;其最终目的就是保证客户收到的产品质量&#xff0c;提高客户满意度&#xff0c;减少退货和维修的数量。质量管…

QGIS之十六过滤器选择要素导出

效果 步骤 1、准备数据 下面这份数据是中国范围内的市级行政区划范围 2、打开表格 3、选择要素 方法1 从图上能看到选中的图形 方法2 4、导出

[文件读取]GoCD 任意文件读取漏洞 (CVE-2021-43287)

1.1漏洞描述 漏洞编号CVE-2021-43287漏洞类型文件读取漏洞等级⭐⭐漏洞环境VULFOCUS攻击方式 描述: GoCD 一款先进的持续集成和发布管理系统,由ThoughtWorks开发。&#xff08;不要和Google的编程语言Go混淆了&#xff01;&#xff09;其前身为CruiseControl,是ThoughtWorks在…

关于Chrome中F12调试Console输入多行

在chrome 浏览器中使用console调试的时&#xff0c;如果想在console中输入多行代码&#xff0c;需要进行换行。 这时我们可以使用 [ Shift Enter ] 。也叫&#xff1a; 软回车。

无标题栏的Qt子窗体在父窗体中停靠时,如何做到严丝合缝

目录 1. 问题的提出 2. 一般实现 3. 加强版 1. 问题的提出 由于业务的要求&#xff0c;需要从父窗体弹出一个子窗体&#xff0c;该子窗体无标题栏&#xff0c;且该子窗体要停靠到父窗体右下角。这个看似很容易的问题&#xff0c;细研起来其实不容易&#xff01; 2. 一般实现…

理工ubuntu20.04电脑配置记录

8188gu无线网卡配置 首先下载github上的文件&#xff0c;进入文件夹 安装make命令 1. 查看usb无线网卡 sudo lsusb|grep 8188 2. 环境准备 sudo apt-get install git make build-essential git dkms linux-headers-$(uname -r) 3. 编译安装 git clone https://github.com…

诡异的bug之dlopen

序 本文给大家分享一个比较诡异的bug&#xff0c;是关于dlopen的&#xff0c;我大致罗列了我项目中使用代码方式及结构&#xff0c;更好的复现这个问题&#xff0c;也帮助大家进一步理解dlopen. 问题复现 以下是项目代码的文件结构&#xff1a; # tree . ├── file1 │ …

【计算机网络笔记】CIDR与路由聚合

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

揭秘Vue中的nextTick:异步更新队列背后的技术原理大揭秘!

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 ⭐ 专栏简介 &#x1f4d8; 文章引言 一、N…

Linux socket编程(3):利用fork实现服务端与多个客户端建立连接

上一节&#xff0c;我们实现了一个客户端/服务端的Socket通信的代码&#xff0c;在这个例子中&#xff0c;客户端连接上服务端后发送一个字符串&#xff0c;而服务端接收到字符串并打印出来后就关闭所有套接字并退出了。 上一节的代码较为简单&#xff0c;在实际的应用中&…

识别伪装IP的网络攻击方法

识别伪装IP的网络攻击可以通过以下几种方法&#xff1a; 观察IP地址的异常现象。攻击者在使用伪装IP地址进行攻击时&#xff0c;往往会存在一些异常现象&#xff0c;如突然出现的未知IP地址、异常的流量等。这些现象可能是攻击的痕迹&#xff0c;需要对此加以留意。 检查网络通…

详解 KEIL C51 软件的使用·设置工程·编绎与连接程序

详解 KEIL C51 软件的使用建立工程-CSDN博客 2. 设置工程 (1)在图 2-15 的画面中点击 会弹出如图 2-16 的对话框.其中有 10 个选择页.选择“Target” 项,也就是图 2-16 的画面. 图 2-16 在图 2-16 中,箭头所指的是晶振的频率值,默认是所选单片机最高的可用频率值.该设置值与单…

大数据Doris(二十二):数据查看导入

文章目录 数据查看导入 数据查看导入 Broker load 导入方式由于是异步的,所以用户必须将创建导入的 Label 记录,并且在查看导入命令中使用 Label 来查看导入结果。查看导入命令在所有导入方式中是通用的,具体语法可执行 HELP SHOW LOAD 查看。 show load order by create…

IEEE--DSConv: Efficient Convolution Operator 论文翻译

论文地址:https://arxiv.org/pdf/1901.01928v1.pdf 目录 摘要 1 介绍 2 相关工作 3 DSConv层 4 量化过程 5 分布偏移 6 优化推断 7 训练 8 结果 8.1 ImageNet 8.2 内存和计算负载 8.3 转移性 9 结论 摘要 我们引入了一种卷积层的变体&#xff0c;称为DSConv&…

【LLM】0x00 大模型简介

0x00 大模型简介 个人问题学习笔记大模型简介LLM 的能力&#xff1a;LLM 的特点&#xff1a; LangChain 简介LangChain 核心组件 小结参考资料 个人问题 1、大模型是什么&#xff1f; 2、ChatGPT 在大模型里是什么&#xff1f; 3、大模型怎么用&#xff1f; 带着问题去学习&a…