首页 > 其他分享 >LeetCode题练习与总结:字典序的第 K 小数字--440

LeetCode题练习与总结:字典序的第 K 小数字--440

时间:2024-12-02 22:32:36浏览次数:7  
标签:count 数字 迭代 -- 440 int prefix LeetCode 前缀

一、题目描述

给定整数 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 <= 10^9

二、解题思路

这个问题可以通过模拟字典序的生成过程来解决。字典序生成过程类似于十叉树的遍历过程,每个节点有10个子节点(0-9)。我们可以使用深度优先搜索(DFS)来模拟这个过程。

以下是解题步骤:

  1. 计算以某个数字 prefix 为前缀的数字的个数。例如,以1为前缀的数字有 [1, 10, 11, …, 19, 100, 101, …, 199, …],直到数字不超过 n。

  2. 使用一个计数器来记录已经遍历过的数字的个数。

  3. 从1开始,对每个数字进行DFS,计算以该数字为前缀的数字个数。如果这个个数大于或等于 k,那么第 k 个数字一定在这个前缀下;否则,将计数器加上这个前缀下的数字个数,并继续下一个数字的DFS。

  4. 当计数器的值等于 k 时,当前的数字就是我们要找的数字。

三、具体代码

class Solution {
    public int findKthNumber(int n, int k) {
        int prefix = 1;
        k--; // 因为从1开始,所以k需要减1
        while (k > 0) {
            int count = count(prefix, n);
            if (count <= k) {
                // 如果当前前缀下的数字个数小于k,说明第k小的数字不在这个前缀下
                // 将计数器减去当前前缀下的数字个数,并移动到下一个前缀
                k -= count;
                prefix++;
            } else {
                // 如果当前前缀下的数字个数大于或等于k,说明第k小的数字在这个前缀下
                // 将计数器减1(因为prefix本身也是其中一个数字),并深入到下一个前缀
                k--;
                prefix *= 10;
            }
        }
        return prefix;
    }

    // 计算以prefix为前缀的数字的个数
    private int count(int prefix, int n) {
        long cur = prefix;
        long next = cur + 1;
        int count = 0;
        while (cur <= n) {
            count += Math.min(n + 1, next) - cur;
            cur *= 10;
            next *= 10;
        }
        return count;
    }
}

四、时间复杂度和空间复杂度

1. 时间复杂度
  • findKthNumber方法中,我们有一个while循环,该循环的迭代次数依赖于k的值。每次迭代中,我们都会调用count方法。

  • count方法中,我们有一个while循环,其迭代次数依赖于prefix的大小以及n的值。在每次迭代中,我们通过乘以10来计算以prefix为前缀的数字的数量。这个循环的迭代次数是O(log(n)/log(10)),因为当cur超过n时,循环会停止。这实际上就是O(log(n)),因为log(10)是一个常数。

  • 在最坏的情况下,我们需要对每个前缀调用count方法,直到找到第k小的数字。在最坏的情况下,我们可能需要遍历所有前缀,直到我们达到n。因此,最坏情况下的时间复杂度是O(log(n)) * O(log(n)),即O(log^2(n))。

2. 空间复杂度
  • findKthNumber方法中,我们使用了几个整型变量(prefix, k, count),这些变量占用的空间是常数级的,即O(1)。

  • count方法中,我们也使用了几个整型变量(cur, next, count),同样这些变量占用的空间也是常数级的,即O(1)。

  • 由于方法调用是迭代的,而不是递归的,我们不需要额外的空间来存储调用栈。因此,整个算法的空间复杂度是O(1)。

五、总结知识点

  • 类定义与成员方法

    • class Solution:定义了一个名为Solution的类。
    • public int findKthNumber(int n, int k):定义了一个公共方法findKthNumber,接受两个整数参数nk,并返回一个整数。
  • 基本数据类型

    • int:表示整数类型,用于定义变量和返回值。
  • 控制结构

    • while循环:用于在不确定迭代次数的情况下重复执行代码块。
    • if-else语句:用于条件判断,根据不同的条件执行不同的代码块。
  • 数学运算

    • 算术运算符:+-*用于基本的算术运算。
    • Math.min:用于计算两个数中的最小值。
  • 逻辑运算

    • long类型的使用:当整数可能超出int类型的范围时,使用long类型来避免溢出。
  • 递归与迭代

    • 迭代方法:代码通过迭代而不是递归来遍历数字前缀,避免了栈溢出的风险。
  • 方法重载与封装

    • private int count(int prefix, int n):定义了一个私有方法count,用于计算以特定前缀开头的数字数量,这是代码封装的一个例子。
  • 变量作用域

    • 局部变量:在方法内部定义的变量(如prefixkcountcurnext)仅在方法内部有效。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

标签:count,数字,迭代,--,440,int,prefix,LeetCode,前缀
From: https://blog.csdn.net/weixin_62860386/article/details/144175875

相关文章

  • 05_VIM编辑器
    VIM编辑器一、VIM编辑器的工作模式命令行模式用户刚刚启动vi/vim,便进入了命令模式。控制屏幕光标的移动,字符、字或行的删除,移动、复制某区域及进入插入模式,或者到末行模式插入模式只有在插入模式下才可以做文本输入,按“ESC”键可回到命令行模式末行模式在命令模式下......
  • 04_重要系统配置文件
    Centos7重要系统配置文件一、网卡配置文件配置文件位置/etc/sysconfig/network-scripts/网卡名详细参数说明HWADDR=网卡MAC地址TYPE=Ethernt网卡类型:以太网PROXY_METHOD=none代理方式:关闭状态BROWSER_ONLY=no只是浏览器(yes|no)BOOTPROTO=s......
  • YOLOv8改进,YOLOv8引入SAConv可切换空洞卷积,二次创新C2f结构
    摘要作者提出的技术结合了递归特征金字塔和可切换空洞卷积,通过强化多尺度特征学习和自适应的空洞卷积,显著提升了目标检测的效果。理论介绍空洞卷积(AtrousConvolution)是一种可以在卷积操作中插入“空洞”来扩大感受野的技术,更有效地捕捉到图像中的大范围上下文信息......
  • LeetCode题练习与总结:排列硬币--441
    一、题目描述你总共有 n 枚硬币,并计划将它们按阶梯状排列。对于一个由 k 行组成的阶梯,其第 i 行必须正好有 i 枚硬币。阶梯的最后一行 可能 是不完整的。给你一个数字 n ,计算并返回可形成 完整阶梯行 的总行数。示例1:输入:n=5输出:2解释:因为第三行不完......
  • 开发嵌入式系统 这五种微处理器该怎么选?从零基础到精通,收藏这篇就够了!
    本文介绍了嵌入式系统中常用的五种微处理器类型:微处理器单元(MPU)、微控制器(MCU)、数字信号处理器(DSP)、现场可编程逻辑门阵列(FPGA)和单片机(SBC)。文章详细阐述了每种处理器的功能、优点、缺点以及选择建议,并列出了一些精选的微处理器产品,供读者参考。任何一个电子系统都需要一......
  • YOLOv11改进,YOLOv11添加SAConv可切换空洞卷积,二次创新C3k2结构
    摘要作者提出的技术结合了递归特征金字塔和可切换空洞卷积,通过强化多尺度特征学习和自适应的空洞卷积,显著提升了目标检测的效果。理论介绍空洞卷积(AtrousConvolution)是一种可以在卷积操作中插入“空洞”来扩大感受野的技术,更有效地捕捉到图像中的大范围上下文信息......
  • 【雷达】对萨德系统ANTPY-2雷达的威力范围仿真计算【含Matlab源码 9707期】
    ......
  • 4.5 将关系字段添加到模型
    在Odoo模型中添加关系字段的全面解析在Odoo开发中,模型之间的关系处理至关重要。关系字段能够有效地建立起不同模型之间的联系,使数据的组织和交互更加合理、高效。今天,我们就深入探讨如何在Odoo模型中添加关系字段。一、关系字段类型概述Odoo模型中的关系字段主要有三种类......
  • kube-proxy的iptables工作模式分析
    系列文章目录iptables基础知识文章目录系列文章目录前言一、kube-proxy介绍1、kube-proxy三种工作模式2、iptables中k8s相关的链二、kube-proxy的iptables模式剖析1.集群内部通过clusterIP访问到pod的流程1.1.流程分析2.从外部访问内部serviceclusterIP后端pod的流......
  • 16、指针
    指针是C语言编程灵魂,但是也不要神话它,掌握住指针的实质很重要。1、指针地址空间        指针:指针变量 用来存储内存地址编号。        地址:内存会按照字节进行编号,一个字节就有一个编号。                  一般地址表示用十六进制 ......