打印1到最大的n位数问题

·  阅读 192

小知识,大挑战!本文正在参与「程序员必备小知识」创作活动。

问题

打印1到最大的n位数

力扣链接

leetcode-cn.com/problems/da…

考察要点

大数问题, 递归思想

思路1

首先根据传入的位n, 来确定它的最大值, 也就是10的n次方减1

然后, 使用for循环来遍历从1到这个最大值的数

时间复杂度: O(10n)

代码1

 public int[] printNumbers(int n) {
   if (n <= 0) return new int[]{};
   // 10的n次方减1, 就是n位数的最大佬
     int end = (int)Math.pow(10, n) - 1;
     int[] res = new int[end];
     
     // 从                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         0开始, 遍历到最大值
     for (int i = 0; i < end; i++) {
         res[i] = i + 1;
     }
     return res;
 }
复制代码

思路2

我们可以使用全排列的思想进行数字的排列, 并且可以使用递归来完成这个全排列

例如: 如果n为2, 那么从高位到低位的全排列顺序为

00, 01, 02, ..., 09

10, 11, 12, ..., 19

当然我们在使用字符数组进行全排列的时候, 要注意去掉高位多余的0

当数字为1位时, 我们可以从字符串的最后开始截取1位

当数字为2位时, 我们可以从字符串的最后开始截取2位

代码2

 // 用来存储全排列数
 int[] res;
 ​
 // 当前要存放到res中的索引
 int count = 0;
 ​
 // 记录9出现的次数
 int nine = 0;
 ​
 // 根据nine进行相应的调整, 也就是我们要从字符数组中的哪一位开始转换为字符串
 int start = 0;
 ​
 // num为单次排列存储字符的数组
 // loop为0-9的数字
 char[] num, loop = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
 ​
 public int[] printNumbers2(int n) {
 ​
   if (n <= 0) return new int[]{};
 ​
     // 初始化数组, 它有10的n次方个元素
     res = new int[(int)Math.pow(10, n) - 1];
 ​
     // 用来存储每次全排列的数
     num = new char[n];
 ​
     // 如果从低到高打印数字的话, 要从字符数组的最后一个元素开始
     start = n - 1;
 ​
     // 开启全排列
     dfs(0, n);
 ​
     return res;
 }
 ​
 void dfs(int x, int n) {
     if(x == n) {
         // 字符数组转换为字符串, 并且根据start去掉字符串里高位中的0
         String s = String.valueOf(num).substring(start);
 ​
         // 将字符串转换为整型数据, 存入返回值中
         if(!s.equals("0")) res[count++] = Integer.parseInt(s);
 ​
         // 每当记录9出现的次数多一个时, 就代表字符数组中的值进了一位
         if(n - start == nine) start--;
         return;
     }
     for(char i : loop) {
         if(i == '9') nine++;
         // 全排列, 从高位开始到低位
         /*
         * 00, 01, 02, 03, ..., 09
         * 10, 11, 12, 13, ..., 19
         * */
 ​
         num[x] = i;
         dfs(x + 1, n);
     }
     nine--;
 }
复制代码

总结

通过本题可以学到在解决大数问题的时候, 我们要学会将其转换为字符串或者字符数组来解决该问题. 如果问题中并没有限定取值范围, 或者可以输入任意大小的整数, 那么我们应该考虑大数问题, 可将其转换为字符串或字符数组来进行解决.

分类:
后端
收藏成功!
已添加到「」, 点击更改