mirror of
https://github.com/ShusenTang/LeetCode.git
synced 2024-09-02 14:20:01 +00:00
Create 386. Lexicographical Numbers.md
This commit is contained in:
parent
57f6c3e8f2
commit
bdc9b08a5d
78
solutions/386. Lexicographical Numbers.md
Normal file
78
solutions/386. Lexicographical Numbers.md
Normal file
@ -0,0 +1,78 @@
|
||||
# [386. Lexicographical Numbers](https://leetcode.com/problems/lexicographical-numbers/)
|
||||
|
||||
# 思路
|
||||
|
||||
题目给定一个n,要求将1~n所有数字按照字典序排序。
|
||||
|
||||
暴力解法就是用STL的sort函数,然后自定义cmp函数,此时时间复杂度为O(nlogn)。但很明显我们可以直接从前往后按照字典序写出来,所以时间复杂度可以是线性的。
|
||||
|
||||
## 思路一、递归
|
||||
想象一下我们该怎样按照字典序将结果写出来,假设n = 119:
|
||||
```
|
||||
初始时为1到9 : 1 2 3 ... 9
|
||||
在上一层每个数后面添加0-9: 10 11 12 13 ... 19 20...29 ... 90...99
|
||||
在上一层每个数后面添加0-9: 100,101,...,109 110,111,...,119
|
||||
|
||||
最终得到的数组 : 1 10 100 101 ...
|
||||
```
|
||||
|
||||
所以这可以用递归实现,大致思路就是每次将一个数push进结果数组中后都要不断尝试在其后添0-9,详见代码。
|
||||
|
||||
时间复杂度O(n)
|
||||
|
||||
## 思路二、迭代
|
||||
也可将上述过程写成迭代的形式,用一个1到n的for循环,用cur表示当前应该填入res[i]的值,初始为1。关键在于如何更新cur:
|
||||
* 如果cur后面添加一个0后没有超过n, 那么在cur后面添加一个0再进入下一循环即可;
|
||||
* 否则
|
||||
* 如果cur本身就不小于n了,那么应该先将其除10(在上图相当于回到上一层,例如119 -> 11);
|
||||
* 将cur加1,如果加1后产生了很多0(即遇到了进位,如109 -> 110),则应该不断除0直到末尾不是0。
|
||||
|
||||
时间复杂度O(n),空间复杂度O(n)
|
||||
|
||||
# C++
|
||||
## 思路一
|
||||
``` C++
|
||||
class Solution {
|
||||
private:
|
||||
void helper(int num, int n, vector<int> &res){
|
||||
res.push_back(num);
|
||||
// 在后面分别添加0-9然后进入递归
|
||||
for(int i = 0; i < 10; i++){
|
||||
int tmp = num*10 + i;
|
||||
if(tmp > n) return;
|
||||
helper(tmp, n, res);
|
||||
}
|
||||
}
|
||||
public:
|
||||
vector<int> lexicalOrder(int n) {
|
||||
vector<int>res;
|
||||
// 初始时为1到9
|
||||
for(int i = 1; i <= min(9, n); i++)
|
||||
helper(i, n, res);
|
||||
|
||||
return res;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## 思路二
|
||||
``` C++
|
||||
class Solution {
|
||||
public:
|
||||
vector<int> lexicalOrder(int n) {
|
||||
vector<int> res(n);
|
||||
int cur = 1;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
res[i] = cur;
|
||||
if (cur * 10 <= n) {
|
||||
cur *= 10;
|
||||
} else {
|
||||
if (cur >= n) cur /= 10;
|
||||
cur += 1;
|
||||
while (cur % 10 == 0) cur /= 10;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
};
|
||||
```
|
Loading…
Reference in New Issue
Block a user