本题意味将1到n所有的int类型数进行字典序排序
一、递归思想
首先想到的是运用分治算法的思想,设采用solve的方法解决问题
对于整数m,若在某一时刻将其插入最终返回的res数组,思考下一步应该插入什么,分两种情况:
(1)若 m*10 <= n,则将 m*10 插入res数组,并继续思考下一步插入什么
(2)若 m < n 且 m%10 < 9 ,则将 m+1 插入res数组,并继续思考下一步插入什么
(此处取模10小于9的情况,是因为当余数为9时,+1后得到的情况已经在条件(1)中考虑到了,加入会产生重复)
下面给出解题代码:
class Solution {
public:
vector<int> lexicalOrder(int n) {
this->n = n;
solve(1);
return res;
}
private:
int n;
vector<int> res;
void solve(int m){
res.push_back(m);
if(m * 10 <= n){
solve(m * 10);
}
if(m < n && m % 10 < 9){
solve(m + 1);
}
}
};
二、非递归思想(栈)
如果不用递归的方法,也可以使用堆栈的思想进行编程,大致过程可以借鉴上文中说到的思想
需要注意的是,因为后进先出的思想,所以需要先将字典序较小的压入栈,再将字典序较大的压入栈,两个if语句块不能颠倒顺序
下面给出具体的代码:
此外附上另一种非递归写法,类似DFS的思想:class Solution { public: vector<int> lexicalOrder(int n) { vector<int> res; stack<int> s; s.push(1); while(!s.empty()){ int tmp = s.top(); s.pop(); res.push_back(tmp); if(tmp < n && tmp % 10 < 9){ s.push(tmp + 1); } if(tmp * 10 <= n){ s.push(tmp * 10); } } return res; } };
class Solution { public: vector<int> lexicalOrder(int n) { vector<int> res; stack<int> s; int x = 1; while(x <= n){ s.push(x); res.push_back(x); x *= 10; } while(!s.empty()){ int tmp = s.top(); s.pop(); if(tmp % 10 == 9) continue; tmp += 1; while(tmp <= n){ s.push(tmp); res.push_back(tmp); tmp *= 10; } } return res; } };