力扣386. 字典序排数

106 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情

力扣386. 字典序排数

一、题目描述:

给你一个整数 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

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/le… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、思路分析:

  1. 这道题考察了什么思想?你的思路是什么?

    哈哈哈,Python的sorted好像自带这个排序算法,但是这样做内存消耗比较大。我们可以使用深度优先搜索,如果num * 10 小于等于n,那么他就在num的后面。然后因为数字是连续的,所以我们要将接下来的num*10的前面几位不变,最后一位从1-9继续放入。直到num * 10 的尾数到了9,或者到达n了返回上一位。

  2. 做题的时候是不是一次通过的,遇到了什么问题,需要注意什么细节?

    不是一次通过的,在实现深度优先算法解题时,我刚开始将num++放到了else之外,这就导致,比如1乘10之后马上又加了1,导致10进不去数组。我将num++放入else块即可。

  3. 有几种解法,哪种解法时间复杂度最低,哪种解法空间复杂度最低,最优解法是什么?其他人的题解是什么,谁的效率更好一些?用不同语言实现的话,哪个语言速度最快?

    这是参考大佬的深度优先算法写出的解法~

     /**
      * Note: The returned array must be malloced, assume caller calls free().
      */
     int* lexicalOrder(int n, int* returnSize){
         int* ret = (int *)malloc(sizeof(int) * n);
         int num = 1;
         for(int i=0;i<n;i++){
             ret[i] = num;
             if(num * 10 <= n){
                 num *= 10;
             }
     ​
             else {
                 while(num % 10 ==9 || num + 1 > n){
                     num /= 10;
                 }
                 num++;
             }
             
         }
         *returnSize = n;
         return ret;
     }
    

三、AC 代码:

 class Solution:
     def lexicalOrder(self, n: int) -> List[int]:
         num_list = []
         for i in range(1,n+1):
             num_list.append(i)
         num_list = sorted(num_list,key=str)
 ​
         return num_list
 ​

image-20220418104104984

四、总结:

这是刚刚做过的蓝桥杯真题啊,可惜我当时比赛时解法比较奇葩~应该过不了多少测试点就会超时。早点看到这道题目就好了!