数字字典序的第K小数字
原题在这里:
概述题意:给定数字n,在数字范围[1,n]中,找到根据字典序的第K小数字。
我首先想到的是构造,然后构造构造着就变成了dfs暴力(指严严实实地从第1小找到第k小)
然后因为1<=k<=n<=1e9,所以T了,然后就是考虑剪枝优化
因为时间关系就没考虑怎么剪枝了,直接看了题解,下次再做吧
my_code:

class Solution { int m, t, l; vector<int> num; int get() { int y = 0; for (int i = 0; i < l; ++i) y = y * 10 + num[i]; return y; } void dfs(int x) { // cout << t << "-> l==" << l << ", " << x << endl; --t; if (t && x * 10 <= m) ++l, dfs(x * 10); //优先扩充0 if (t && num[l - 1] < 9 && x < m) //增值进位 ++num[l - 1], dfs(get()); if (t && num[l - 1] == 9) num[--l] = 0; return; } public: int findKthNumber(int n, int k) { m = n, t = k, l = 1; num = vector<int>(10, 0); dfs(num[0] = 1); return get(); } };
其实我起初就是想的剪枝那方面的东西,但是我最优考虑还是能写暴力构造就写了,再去看题解的时候好歹没那么空脑袋
下面是官方的分析,运用字典树思想分析构造:
分析得很好,我的注解写在code里面了
code:
class Solution { int getsum(long x, long n) { //在树x下小于等于n的数量 long first = x, second = x + 1, sum = 0; /* first 表示x 分支左侧0开始的数字 second表示x+1分支左侧0开始的数字 second-first就表示当前层数的数量 如果当前数字first小于等于n那么还可以继续往下一层走 */ while (first <= n) { // cout << "x=" << x << ", sum+=" << min(n + 1, second) - first << endl; sum += min(n + 1, second) - first; //累计当层数量 first *= 10, second *= 10; //下层移动 } return sum; } public: int findKthNumber(int n, int k) { int x = 1; while (k > 1) { int sum = getsum(x, n); if (sum < k)//如果当前层sum小于k,那么应该x右移 k -= sum, ++x; else//否则x下移 --k, x *= 10; } return x; } };
【Over】
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!