想了解更多數據結構以及算法題,可以關注微信公衆號“數據結構和算法”,每天一題爲你精彩解答。也可以掃描下面的二維碼關注
給定一個整數 n, 返回從 1 到 n 的字典順序。
例如,
給定 n =13,返回 [1,10,11,12,13,2,3,4,5,6,7,8,9] 。
請儘可能的優化算法的時間複雜度和空間複雜度。輸入的數據 n 小於等於 5,000,000。
public List<Integer> lexicalOrder(int n) {
List<Integer> res = new ArrayList<>();
for (int i = 1; i < 10; ++i) {
dfs(i, n, res);
}
return res;
}
public void dfs(int cur, int n, List<Integer> res) {
if (cur > n)
return;
res.add(cur);
for (int i = 0; i < 10; ++i) {
dfs(10 * cur + i, n, res);
}
}
解這題之前實現要明白什麼是字典序,其實就是類似於字典一樣,根據字母的順序進行排列,我們先來看下面的圖
我們可以把它看成有9棵樹,每棵樹的根節點的值分別是從1到9,並且每棵樹都有10個子節點,並且每個子節點又會有10個子節點……
1,代碼3到5行分別遍歷這9棵樹。
2,方法dfs對每棵樹執行dfs(深度優先搜索)
我們還可以把遞歸改爲非遞歸的方式,代碼如下
public List<Integer> lexicalOrder(int n) {
List<Integer> ans = new ArrayList<>(n);
int curr = 1;
for (int i = 1; i <= n; ++i) {
ans.add(curr);
if (curr * 10 <= n) {
curr *= 10;
} else {
while (curr % 10 == 9 || curr == n)
curr /= 10;
curr++;
}
}
return ans;
}