トピック
指定された整数の合計 で 辞書式 に 最小の数値を返します n
。 k
[1, n]
k
例1
输入: n = 13, k = 2
输出: 10
解释: 字典序的排列是 [1, 10, 11, 12, 13, 2, 3, 4, 5, 6, 7, 8, 9],所以第二小的数字是 10。
复制代码
例2
输入: n = 1, k = 1
输出: 1
复制代码
ヒント
1 <= k <= n <= 109
答え
問題が単純であるほど、問題は大きくなります。問題は1文であり、問題は長い間解決されます。
ポリツリーのプレオーダートラバーサル
graph TD
root --> 1
root --> 2
root --> 3[...]
root --> 9
1 --> 10
1 --> 11
1 --> 12[...]
1 --> 19
10 --> 100
10 --> 101
10 --> 102[...]
10 --> 109
- 1からnまでの辞書式順序は、上記の不完全な9項ツリーのノードと見なすことができます。
- 上記の9元ツリーノードからプレオーダーでトラバースされたk番目のノードは、辞書式順序でk番目に小さい数です。
上記の写真とテキストは解決策のアイデアを与えています、以下はアイデアをコードに変換することです
- 1からnまでの9項ツリーを直接構築することは可能ですか?はい、はい、しかし複雑さは少し高いです。k番目のツリーを見つけるだけで、完全なツリーを構築する必要があります。これは失う価値がありません。
- ツリーの特性を使用して、プレオーダートラバーサルをシミュレートし、時間の複雑さを軽減できます。
シミュレートする方法は?
-
getChildrenメソッドがある場合は、現在のノードの下に子ノードがいくつあるかを取得できます。
- たとえば、1から100まで、1の下に12のノードがあります。
-
子ノードの数childがk未満であると想定します
- 現在のノードにすべての子ノードが含まれていると言うのは答えではありません。答えは、現在のノードの他の兄弟にあります。
- kから子を引いたもの;そして子ノードの数が現在のノードの兄弟ノードでk-子より少ないかどうかを調べます
- 上記の操作を繰り返します
-
子ノードの数が子>=kの場合
- 回答は、現在のノードまたは現在のノードの子ノードに存在する必要があります
- 子ノードの子ノードの数とk-1の関係を再帰的に求めます
- 上記の操作を繰り返します
上記のアイデアに従って、次のようにコードを編集します。
完全なコード
var findKthNumber = function (n, k) {
let count = 1;
k--;
while (k > 0) {
const children = getChildren(count);
if (children <= k) {
k -= children;
count++;
} else {
count = count * 10;
k--;
}
}
return count;
function getChildren(c) {
let child = 0;
let left = c;
let right = c;
while (left <= n) {
child += Math.min(right, n) - left + 1;
left *= 10;
right = right * 10 + 9;
}
return child;
}
};
复制代码
エピローグ
著者のレベルは限られています。欠点がある場合は、私を訂正してください。コメントや提案は、コメント領域で閲覧して議論することを歓迎します。