来源:力扣(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. 【机器学习】李宏毅——Flow-based Generative Models

    前文我介绍了部分关于生成学习的内容,可以参考我这篇博文点此 前面介绍的各个生成模型,都存在一定的问题: 对于PixelRNN这类模型来说,就是从左上角的像素开始一个个地进行生成,那么这个生成顺序是否合 ...

  2. VsCode搭建C语言运行环境以及终端乱码问题解决

    在VsCode中搭建C/C++运行环境需要先安装以下插件 1.安装c/c++插件 2.安装code runner插件 当然也可以安装一些其他的美化插件根据个人习惯,但是以上这两个是必装的. 安装好插件 ...

  3. c#5.0(.net 4.5之后)的 Async+await+Task的异步机制的调试笔记

    1.)无返回值的情况(异步也是基于线程). using System; using System.Collections.Generic; using System.Linq; using Syste ...

  4. 基于Spark的均值漂移算法在网络舆情聚类中的应用

    知网链接 原文链接 张京坤,  王怡怡 软件导刊   2020年19卷第9期 页码:190-195 DOI:10.11907/rjdk.192529 出版日期:2020-9-15 摘 要: 为了改善网 ...

  5. Shell 基本常识

    Shell 进入命令行 启动 shell 常用命令 系统管理命令 处理数据命令 Linux 基础管理命令 用户管理 管理文件系统 软件包管理系统 使用容器管理软件 理解 shell 子 shell 环 ...

  6. python进阶之路16 模块入门

    索引取值与迭代取值的差异 l1 = [11,22,33,44,55] 1.索引取值 可以任意位置任意次数取值 不支持无序类型的数据取值 2.迭代取值 只能从前往后依次取值无法后退 支持所有类型的数据取 ...

  7. SPOJLCMSUM - LCM Sum

    简要题意 \(T\) 组数据,每组数据给出一个 \(n\),计算: \[\sum_{i=1}^{n}{\operatorname{lcm}(i,n)} \] \(1 \leq T \leq 3\tim ...

  8. nmap脚本详解

    nmap --script 前言 我们通过nmap script来大幅扩展nmap的功能,nmap具有强大的脚本引擎NSE(Nmap Scripting Engine),它允许用户编写(和共享)简单的 ...

  9. 二十一、B树的定义、查找、插入和删除

    一.B树的定义 一棵m阶的B树,或为空树,或为满足下列特性的m叉树: (1)树中每个结点至多有m棵子树:(2)B树是所有结点的平衡因子均等于0的多路平衡查找树:(3)若根结点不是叶子结点,则至少有两棵 ...

  10. 动力节点——day01

    eclipse的快捷键: 1.ctrl+d删除一行 2.ctrl+1进行纠错 3.alt+/自动补全 4.单行注释ctrl+/ 5.多行注释ctrl+shift+/ 取消ctrl+shift+\ 6. ...