数字字典序的第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();
    }
};
dfs暴力构造
复制代码

 

 

其实我起初就是想的剪枝那方面的东西,但是我最优考虑还是能写暴力构造就写了,再去看题解的时候好歹没那么空脑袋

下面是官方的分析,运用字典树思想分析构造:

 

 

 

分析得很好,我的注解写在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】

 

posted @   Renhr  阅读(53)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!
点击右上角即可分享
微信分享提示