LeetCode题练习与总结:字典序排数--386

server/2024/12/2 15:37:03/

一、题目描述

给你一个整数 n ,按字典序返回范围 [1, n] 内所有整数。

你必须设计一个时间复杂度为 O(n) 且使用 O(1) 额外空间的算法

示例 1:

输入:n = 13
输出:[1,10,11,12,13,2,3,4,5,6,7,8,9]

示例 2:

输入:n = 2
输出:[1,2]

提示:

  • 1 <= n <= 5 * 10^4

二、解题思路

  1. 我们可以从1开始,每次找到当前数字的下一个字典序的数字。例如,如果当前数字是1,那么下一个字典序的数字是10,而不是2。
  2. 我们可以通过在当前数字后面添加一个0来找到下一个字典序的数字。但是,如果添加0后的数字大于n,我们需要回退到上一个数字,然后增加1,再重复这个过程。
  3. 当我们找到一个数字,如果它小于等于n,我们就将其添加到结果列表中,然后继续寻找下一个字典序的数字。
  4. 我们重复这个过程,直到我们找到的所有数字都大于n。

三、具体代码

import java.util.ArrayList;
import java.util.List;class Solution {public List<Integer> lexicalOrder(int n) {List<Integer> result = new ArrayList<>();int current = 1;for (int i = 1; i <= n; i++) {result.add(current);if (current * 10 <= n) {current *= 10;} else {while (current % 10 == 9 || current + 1 > n) {current /= 10;}current++;}}return result;}
}

解释:

  • 我们初始化current为1,并将其添加到结果列表中。
  • 在每次循环中,我们检查current * 10是否小于等于n。如果是,我们将current乘以10,以找到下一个字典序的数字。
  • 如果current * 10大于n,我们需要找到下一个数字。我们通过不断除以10来跳过以9结尾的数字,或者当current + 1大于n时停止。
  • 最后,我们将current加1,以找到下一个字典序的数字,并继续循环直到找到所有数字。

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

1. 时间复杂度
  • 循环次数:代码中有一个for循环,循环次数为n(即输入的整数n)。
  • 循环体内的操作:每次循环中,我们添加一个数字到结果列表,这个操作是常数时间复杂度O(1)。接下来,我们可能需要对current进行多次除以10的操作,直到找到下一个合适的数字。在最坏的情况下,current需要除以10的次数最多为数字的位数,由于n的最大值为5 * 10^4,所以current的位数最多为6位(即最大为59999),这意味着除以10的操作最多执行6次,这是一个常数。
  • 综合考虑:由于每次循环中的操作都是常数时间复杂度,并且循环次数为n,所以总的时间复杂度为O(n)。
2. 空间复杂度
  • 结果列表:我们创建了一个列表来存储结果,列表的大小为n,因此需要O(n)的空间。
  • 其他变量:除了结果列表之外,我们只使用了几个整数变量(如current和循环变量i),这些变量占用常数空间O(1)。
  • 综合考虑:虽然我们使用了O(n)的空间来存储结果,但是题目要求不包括返回结果所需的空间。因此,除了返回结果所需的空间之外,算法使用的额外空间为O(1)。

五、总结知识点

  • Java 类定义

    • class 关键字用于定义一个类。
    • 类名通常首字母大写,这里是 Solution
  • 成员方法

    • public 关键字表示方法的访问权限,允许其他类访问。
    • List<Integer> 表示方法返回一个整数列表。
    • 方法名为 lexicalOrder,接收一个整数参数 n
  • Java 集合框架

    • List 接口用于表示有序集合。
    • ArrayList 类实现了 List 接口,用于创建动态数组。
  • 循环控制

    • for 循环用于重复执行代码块,直到给定的条件不再满足。
    • 循环变量 i 用于跟踪循环的次数。
  • 条件语句

    • if-else 语句用于根据条件执行不同的代码块。
    • while 循环用于在给定条件为真时重复执行代码块。
  • 算术运算

    • * 表示乘法运算。
    • / 表示除法运算。
    • % 表示取模运算,用于判断一个数是否能被另一个数整除。
  • 赋值运算

    • = 用于赋值。
    • ++ 用于自增操作。
  • 逻辑运算符

    • || 表示逻辑或运算。
    • && 表示逻辑与运算。
  • 方法调用

    • add 方法用于向列表中添加元素。
  • 返回语句

    • return 关键字用于从方法中返回值。

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


http://www.ppmy.cn/server/140589.html

相关文章

选项式api和组合式api

在 Vue 3 中&#xff0c;选项式 API&#xff08;Options API&#xff09;和 组合式 API&#xff08;Composition API&#xff09;是两种不同的编写组件的方式。Vue 3 引入了组合式 API&#xff0c;旨在改善 Vue 2.x 中的选项式 API 的一些限制&#xff0c;特别是在大型项目中&a…

【LeetCode】【算法】48. 旋转图像

LeetCode 48. 旋转图像 题目描述 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 思路 思路&#xff1a;再次拜见K神&#xf…

OpenAI大事记;GPT到ChatGPT参数量进化

目录 OpenAI大事记 GPT到ChatGPT参数量进化 OpenAI大事记 GPT到ChatGPT参数量进化 ChatGPT是从初代 GPT逐渐演变而来的。在进化的过程中,GPT系列模型的参数数量呈指数级增长,从初代GPT的1.17亿个参数,到GPT-2的15 亿个参数,再到 GPT-3的1750 亿个参数。模型越来越大,训练…

走进算法大门---双指针问题(一)

一.双指针算法介绍 概念&#xff1a;双指针是指在遍历数据结构&#xff08;如数组、链表等&#xff09;时使用两个指针&#xff0c;通过特定的移动规则来解决问题。这两个指针可以同向移动&#xff0c;也可以相向移动。 同向双指针&#xff1a;常用于解决需要两个位置信息的问…

线性代数:Matrix2x2和Matrix3x3

今天整理自己的框架代码&#xff0c;将Matrix2x2和Matrix3x3给扩展了一下&#xff0c;发现网上unity数学计算相关挺少的&#xff0c;所以记录一下。 首先扩展Matrix2x2&#xff1a; using System.Collections; using System.Collections.Generic; using Unity.Mathemati…

释放专利力量:Patently 如何利用向量搜索和 NLP 简化协作

作者&#xff1a;来自 Elastic Matt Scourfield, Andrew Crothers, Brian Lambert 组织依靠知识产权 (IP) 来推动创新、保持竞争优势并创造收入来源。对于希望将新产品推向市场的公司来说&#xff0c;弄清楚谁拥有哪些专利是一项必不可少的能力。搜索数百万项专利可能既困难又耗…

C++ 的发展

目录 C 的发展总结&#xff1a;​编辑 1. C 的早期发展&#xff08;1979-1985&#xff09; 2. C 标准化过程&#xff08;1985-1998&#xff09; 3. C 标准演化&#xff08;2003-2011&#xff09; 4. C11&#xff08;2011年&#xff09; 5. C14&#xff08;2014年&#xf…

基于SpringBoot的“乐校园二手书交易管理系统”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“乐校园二手书交易管理系统”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统首页界面图 用户注册界面图 二手…