来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/k-th-smallest-in-lexicographical-order

题目描述

给定整数 n 和 k,返回  [1, n] 中字典序第 k 小的数字。

示例 1:

输入: n = 13, k = 2
输出: 10
解释: 字典序的排列是 [1, 10, 11, 12, 13, 2, 3, 4, 5, 6, 7, 8, 9],所以第二小的数字是 10。
示例 2:

输入: n = 1, k = 1
输出: 1

提示:

1 <= k <= n <= 109

解题思路

根据题意,最简单的方法是造一棵字典树,将1-n的数字全部存入,并且前序遍历所有数字,第k个就是答案,但是观察数据大小,应该会超时,果然就超时了。

通过观察,发现造出的字典树是一颗完全树,所以可以利用这个规律来虚拟字典上,并不需要真正造一颗树。对于结点i来说,i拥有的子树中结点个数为icount, 如果icount < k,那么寻找的结点不在这个子树中,寻找下一个相邻的结点,否则,寻找的结点就在这颗子树中,向下寻找i结点的每个子树。

由于字典树是满二叉树,所以求取i的结点数可以用虚拟的层次遍历,假设第j层左结点是x1,最右结点是x2,那么这一层的结点个数就是x2 - x1 + 1,下一层左结点x3 = x1 * 10, 右结点x4 = x2 * 10 + 9 或者 n。

代码展示

字典树 + dfs:


class Solution {
public:
    struct TreeNode
    {
        int val;
        TreeNode* ch[10];
        TreeNode(int val)
        {
            this->val = val;
            for (int i = 0; i < 10; i++)
            {
                this->ch[i] = NULL;
            }
        }
    };
    int miRet = 0;
    void dfs(TreeNode *root, int &k)
    {
        if (!root) return;
        k--;
        if (k < 0) return;
        if (k == 0)
        {
            miRet = root->val;
            return;
        }
        for (int i = 0; i < 10; i++)
            dfs(root->ch[i], k);
    }
    int findKthNumber(int n, int k) {
        TreeNode* root = new TreeNode(0);
        for (int i = 1; i <= n; i++)
        {
            TreeNode* p = root;
            string str = to_string(i);
            for (int j = 0; j < str.size(); j++)
            {
                if (p->ch[str[j] - '0'] == NULL)
                {
                    p->ch[str[j] - '0'] = new TreeNode(0);
                }
                p = p->ch[str[j] - '0'];
            }
            p->val = i;
        }
        int iTemp = k + 1;
        dfs(root, iTemp);
        return miRet;
    }
};
 

虚拟字典树+ 虚拟遍历:

class Solution {
public:
int MyCount(int i, long n)
{
int iCount = 0;
long iFirst = i;
long iLast = i;
while(iFirst <= n)
{
iCount += min(iLast, n) - iFirst + 1;
iFirst *= 10;
iLast = iLast * 10 + 9;
}
return iCount; } int findKthNumber(int n, int k) {
int iCur = 1;
k--;
while(k > 0)
{
int iCount = MyCount(iCur, n);
if(iCount <= k)
{
k -= iCount;
iCur++;
}
else
{
iCur *= 10;
k--;
}
}
return iCur;
}
};

运行结果

LeetCode-440 字典序的第K小数字的更多相关文章

  1. Java实现 LeetCode 440 字典序的第K小数字

    440. 字典序的第K小数字 给定整数 n 和 k,找到 1 到 n 中字典序第 k 小的数字. 注意:1 ≤ k ≤ n ≤ 109. 示例 : 输入: n: 13 k: 2 输出: 10 解释: ...

  2. 440. 字典序的第K小数字 + 字典树 + 前缀 + 字典序

    440. 字典序的第K小数字 LeetCode_440 题目描述 方法一:暴力法(必超时) package com.walegarrett.interview; /** * @Author WaleG ...

  3. LeetCode 386——字典序的第 K 小数字

    1. 题目 2. 解答 字典序排数可以看做是第一层节点分别为 1-9 的十叉树,然后我们在树上找到第 K 小的数字即可.因此,我们需要分别统计以 1-9 为根节点的每个树的节点个数.如果 K 小于当前 ...

  4. 440 K-th Smallest in Lexicographical Order 字典序的第K小数字

    给定整数 n 和 k,找到 1 到 n 中字典序第 k 小的数字.注意:1 ≤ k ≤ n ≤ 109.示例 :输入:n: 13   k: 2输出:10解释:字典序的排列是 [1, 10, 11, 1 ...

  5. [Swift]LeetCode440. 字典序的第K小数字 | K-th Smallest in Lexicographical Order

    Given integers n and k, find the lexicographically k-th smallest integer in the range from 1 to n. N ...

  6. 字典序的第K小数字

    今天zyb参加一场面试,面试官听说zyb是ACMer之后立马抛出了一道算法题给zyb:有一个序列,是1到n的一种排列,排列的顺序是字典序小的在前,那么第k个数字是什么?例如n=15,k=7, 排列顺序 ...

  7. Leetcode 440.字典序第k小的数字

    字典序第k小的数字 给定整数 n 和 k,找到 1 到 n 中字典序第 k 小的数字. 注意:1 ≤ k ≤ n ≤ 109. 示例 : 输入: n: 13 k: 2 输出: 10 解释: 字典序的排 ...

  8. Java实现 LeetCode 719 找出第 k 小的距离对(二分搜索法+二分猜数字)

    719. 找出第 k 小的距离对 给定一个整数数组,返回所有数对之间的第 k 个最小距离.一对 (A, B) 的距离被定义为 A 和 B 之间的绝对差值. 示例 1: 输入: nums = [1,3, ...

  9. [LeetCode] K-th Smallest in Lexicographical Order 字典顺序的第K小数字

    Given integers n and k, find the lexicographically k-th smallest integer in the range from 1 to n. N ...

  10. LeetCode 230.二叉树中第k小的元素

    题目: 给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素. 说明:你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数. 这道题在leetCode上难 ...

随机推荐

  1. 三道MISC的writeup

    (1)背时 描述:腐烂了,变异了,太背时了...... 附件为一个压缩包 解题思路: 1.打开压缩包,发现有一个描述:v(51wA:I7uABi#Bx(T 2.将v(51wA:I7uABi#Bx(T进 ...

  2. 文件压缩和vi编辑器

    一.压缩,解压缩 1.gzip 和 bzip2 gzip和bzip都是压缩软件,比如windows里的好压和360 压缩或微软自带的等等 命令格式是:gzip或者bzip  + 0-9的压缩等级(数字 ...

  3. 一个简单的工具开发:从学生端更新程序部署工具说起,浅谈qt中自定义控件制作和调用、TCP协议下文件的收发 、以及可执行文件的打包

    一个简单的工具开发:从学生端更新程序部署工具说起,浅谈qt中ui的使用和TCP协议下文件的收发.以及可执行文件的打包 写在前面,Qt Designer是一个非常操蛋的页面编辑器,它非常的...怎么说呢 ...

  4. 手把手教你一套完善且高效的k8s离线部署方案

    作者:郝建伟 背景 面对更多项目现场交付,偶而会遇到客户环境不具备公网条件,完全内网部署,这就需要有一套完善且高效的离线部署方案. 系统资源 编号 主机名称 IP 资源类型 CPU 内存 磁盘 01 ...

  5. paozhu c++ web framework 框架原理

    paozhu c++ web framework 框架原理 paozhu c++ web framework 使用 asio 网络库,如果用动态库方式还要boost库. paozhu框架 使用两个线程 ...

  6. [seaborn] seaborn学习笔记4-核密度图DENSITYPLOT

    文章目录 4 核密度图Densityplot 1. 基础核密度图绘制 Basic density plot 2. 核密度图的区间控制 Control bandwidth of density plot ...

  7. 一文详解RocketMQ的存储模型

    摘要:RocketMQ 优异的性能表现,必然绕不开其优秀的存储模型. 本文分享自华为云社区<终于弄明白了 RocketMQ 的存储模型>,作者:勇哥java实战分享. RocketMQ 优 ...

  8. NW js 打包入门教程

    NW js 打包入门教程 NW.JS的安装与打包_u013288292的博客-CSDN博客_nwjs打包

  9. 《Effective C++》构造、析构、赋值运算

    Item 05:了解C++默默编写并调用了哪些函数 总结:编译器可以暗自为class创建default 构造函数.copy构造函数.copy assignment操作符,以及析构函数. (这一小节比较 ...

  10. [cocos2d-x]关于屏幕适配

    第一步:理解屏幕分辨率和设计分辨率 通过这个图可以很容易理解,设计分辨率就是你能够进行纹理绘制的大小,而屏幕分辨率就是你的画框大小.而两者之间的适配,通过cocos2dx自带的几种适配方案来进行适配, ...