@lytjs/common-algorithm 6.4.0 → 6.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,33 +1,33 @@
1
- # @lytjs/common-algorithm
2
-
3
- 算法工具,提供最长递增子序列(LIS)等算法实现。
4
-
5
- ## 安装
6
-
7
- ```bash
8
- pnpm add @lytjs/common-algorithm
9
- ```
10
-
11
- ## API
12
-
13
- ### `getSequence(arr: number[]): number[]`
14
-
15
- 求最长递增子序列,返回原数组中构成 LIS 的元素索引数组。
16
-
17
- 时间复杂度:O(n log n)
18
-
19
- ```typescript
20
- import { getSequence } from '@lytjs/common-algorithm';
21
-
22
- const indices = getSequence([10, 9, 2, 5, 3, 7, 101, 18]);
23
- // indices = [2, 4, 5, 6]
24
- // 对应值 = [2, 3, 7, 101]
25
-
26
- const arr = [10, 9, 2, 5, 3, 7, 101, 18];
27
- const lis = indices.map((i) => arr[i]);
28
- // lis = [2, 3, 7, 101]
29
- ```
30
-
31
- ## License
32
-
33
- MIT
1
+ # @lytjs/common-algorithm
2
+
3
+ 算法工具,提供最长递增子序列(LIS)等算法实现。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ pnpm add @lytjs/common-algorithm
9
+ ```
10
+
11
+ ## API
12
+
13
+ ### `getSequence(arr: number[]): number[]`
14
+
15
+ 求最长递增子序列,返回原数组中构成 LIS 的元素索引数组。
16
+
17
+ 时间复杂度:O(n log n)
18
+
19
+ ```typescript
20
+ import { getSequence } from '@lytjs/common-algorithm';
21
+
22
+ const indices = getSequence([10, 9, 2, 5, 3, 7, 101, 18]);
23
+ // indices = [2, 4, 5, 6]
24
+ // 对应值 = [2, 3, 7, 101]
25
+
26
+ const arr = [10, 9, 2, 5, 3, 7, 101, 18];
27
+ const lis = indices.map((i) => arr[i]);
28
+ // lis = [2, 3, 7, 101]
29
+ ```
30
+
31
+ ## License
32
+
33
+ MIT
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;AAeO,SAAS,YAAuC,GAAA,EAAyB;AAC9E,EAAA,MAAM,MAAM,GAAA,CAAI,MAAA;AAChB,EAAA,IAAI,GAAA,KAAQ,CAAA,EAAG,OAAO,EAAC;AAGvB,EAAA,MAAM,QAAkB,EAAC;AAEzB,EAAA,MAAM,SAAmB,IAAI,KAAA,CAAM,GAAG,CAAA,CAAE,KAAK,EAAE,CAAA;AAE/C,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,EAAK,CAAA,EAAA,EAAK;AAC5B,IAAA,MAAM,GAAA,GAAM,IAAI,CAAC,CAAA;AAGjB,IAAA,IAAI,IAAA,GAAO,CAAA;AACX,IAAA,IAAI,QAAQ,KAAA,CAAM,MAAA;AAElB,IAAA,OAAO,OAAO,KAAA,EAAO;AACnB,MAAA,MAAM,GAAA,GAAO,OAAO,KAAA,KAAW,CAAA;AAC/B,MAAA,IAAI,GAAA,CAAI,KAAA,CAAM,GAAG,CAAE,IAAK,GAAA,EAAK;AAC3B,QAAA,IAAA,GAAO,GAAA,GAAM,CAAA;AAAA,MACf,CAAA,MAAO;AACL,QAAA,KAAA,GAAQ,GAAA;AAAA,MACV;AAAA,IACF;AAGA,IAAA,IAAI,OAAO,CAAA,EAAG;AACZ,MAAA,MAAA,CAAO,CAAC,CAAA,GAAI,KAAA,CAAM,IAAA,GAAO,CAAC,CAAA;AAAA,IAC5B;AAEA,IAAA,IAAI,IAAA,KAAS,MAAM,MAAA,EAAQ;AACzB,MAAA,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,IACd,CAAA,MAAO;AACL,MAAA,KAAA,CAAM,IAAI,CAAA,GAAI,CAAA;AAAA,IAChB;AAAA,EACF;AAGA,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,IAAI,OAAA,GAAU,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA;AACpC,EAAA,OAAO,YAAY,EAAA,EAAI;AACrB,IAAA,MAAA,CAAO,KAAK,OAAO,CAAA;AACnB,IAAA,OAAA,GAAU,OAAO,OAAO,CAAA;AAAA,EAC1B;AAEA,EAAA,OAAO,OAAO,OAAA,EAAQ;AACxB","file":"index.cjs","sourcesContent":["/**\r\n * @lytjs/common-algorithm\r\n * 算法工具 - 最长递增子序列(LIS)\r\n */\r\n\r\n/**\r\n * 求最长递增子序列(Longest Increasing Subsequence)\r\n * 返回的是原数组中构成 LIS 的元素索引数组\r\n *\r\n * 算法: patience sorting + binary search\r\n * 时间复杂度:O(n log n)\r\n *\r\n * @param arr - 输入数组\r\n * @returns 构成 LIS 的索引数组\r\n */\r\nexport function getSequence<T extends string | number>(arr: Array<T>): number[] {\r\n const len = arr.length;\r\n if (len === 0) return [];\r\n\r\n // tails[i] 存储长度为 i+1 的 LIS 的最小末尾值的索引\r\n const tails: number[] = [];\r\n // parent[i] 存储 arr[i] 在 LIS 中的前驱索引\r\n const parent: number[] = new Array(len).fill(-1);\r\n\r\n for (let i = 0; i < len; i++) {\r\n const val = arr[i]!;\r\n\r\n // 二分查找:找到 tails 中第一个 >= val 的位置\r\n let left = 0;\r\n let right = tails.length;\r\n\r\n while (left < right) {\r\n const mid = (left + right) >>> 1;\r\n if (arr[tails[mid]!]! < val) {\r\n left = mid + 1;\r\n } else {\r\n right = mid;\r\n }\r\n }\r\n\r\n // left 就是 val 应该放置的位置\r\n if (left > 0) {\r\n parent[i] = tails[left - 1]!;\r\n }\r\n\r\n if (left === tails.length) {\r\n tails.push(i);\r\n } else {\r\n tails[left] = i;\r\n }\r\n }\r\n\r\n // 回溯构建 LIS 的索引序列\r\n const result: number[] = [];\r\n let current = tails[tails.length - 1]!;\r\n while (current !== -1) {\r\n result.push(current);\r\n current = parent[current]!;\r\n }\r\n\r\n return result.reverse();\r\n}\r\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;AAeO,SAAS,YAAuC,GAAA,EAAyB;AAC9E,EAAA,MAAM,MAAM,GAAA,CAAI,MAAA;AAChB,EAAA,IAAI,GAAA,KAAQ,CAAA,EAAG,OAAO,EAAC;AAGvB,EAAA,MAAM,QAAkB,EAAC;AAEzB,EAAA,MAAM,SAAmB,IAAI,KAAA,CAAM,GAAG,CAAA,CAAE,KAAK,EAAE,CAAA;AAE/C,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,EAAK,CAAA,EAAA,EAAK;AAC5B,IAAA,MAAM,GAAA,GAAM,IAAI,CAAC,CAAA;AAGjB,IAAA,IAAI,IAAA,GAAO,CAAA;AACX,IAAA,IAAI,QAAQ,KAAA,CAAM,MAAA;AAElB,IAAA,OAAO,OAAO,KAAA,EAAO;AACnB,MAAA,MAAM,GAAA,GAAO,OAAO,KAAA,KAAW,CAAA;AAC/B,MAAA,IAAI,GAAA,CAAI,KAAA,CAAM,GAAG,CAAE,IAAK,GAAA,EAAK;AAC3B,QAAA,IAAA,GAAO,GAAA,GAAM,CAAA;AAAA,MACf,CAAA,MAAO;AACL,QAAA,KAAA,GAAQ,GAAA;AAAA,MACV;AAAA,IACF;AAGA,IAAA,IAAI,OAAO,CAAA,EAAG;AACZ,MAAA,MAAA,CAAO,CAAC,CAAA,GAAI,KAAA,CAAM,IAAA,GAAO,CAAC,CAAA;AAAA,IAC5B;AAEA,IAAA,IAAI,IAAA,KAAS,MAAM,MAAA,EAAQ;AACzB,MAAA,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,IACd,CAAA,MAAO;AACL,MAAA,KAAA,CAAM,IAAI,CAAA,GAAI,CAAA;AAAA,IAChB;AAAA,EACF;AAGA,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,IAAI,OAAA,GAAU,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA;AACpC,EAAA,OAAO,YAAY,EAAA,EAAI;AACrB,IAAA,MAAA,CAAO,KAAK,OAAO,CAAA;AACnB,IAAA,OAAA,GAAU,OAAO,OAAO,CAAA;AAAA,EAC1B;AAEA,EAAA,OAAO,OAAO,OAAA,EAAQ;AACxB","file":"index.cjs","sourcesContent":["/**\n * @lytjs/common-algorithm\n * 算法工具 - 最长递增子序列(LIS)\n */\n\n/**\n * 求最长递增子序列(Longest Increasing Subsequence)\n * 返回的是原数组中构成 LIS 的元素索引数组\n *\n * 算法: patience sorting + binary search\n * 时间复杂度:O(n log n)\n *\n * @param arr - 输入数组\n * @returns 构成 LIS 的索引数组\n */\nexport function getSequence<T extends string | number>(arr: Array<T>): number[] {\n const len = arr.length;\n if (len === 0) return [];\n\n // tails[i] 存储长度为 i+1 的 LIS 的最小末尾值的索引\n const tails: number[] = [];\n // parent[i] 存储 arr[i] 在 LIS 中的前驱索引\n const parent: number[] = new Array(len).fill(-1);\n\n for (let i = 0; i < len; i++) {\n const val = arr[i]!;\n\n // 二分查找:找到 tails 中第一个 >= val 的位置\n let left = 0;\n let right = tails.length;\n\n while (left < right) {\n const mid = (left + right) >>> 1;\n if (arr[tails[mid]!]! < val) {\n left = mid + 1;\n } else {\n right = mid;\n }\n }\n\n // left 就是 val 应该放置的位置\n if (left > 0) {\n parent[i] = tails[left - 1]!;\n }\n\n if (left === tails.length) {\n tails.push(i);\n } else {\n tails[left] = i;\n }\n }\n\n // 回溯构建 LIS 的索引序列\n const result: number[] = [];\n let current = tails[tails.length - 1]!;\n while (current !== -1) {\n result.push(current);\n current = parent[current]!;\n }\n\n return result.reverse();\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";AAeO,SAAS,YAAuC,GAAA,EAAyB;AAC9E,EAAA,MAAM,MAAM,GAAA,CAAI,MAAA;AAChB,EAAA,IAAI,GAAA,KAAQ,CAAA,EAAG,OAAO,EAAC;AAGvB,EAAA,MAAM,QAAkB,EAAC;AAEzB,EAAA,MAAM,SAAmB,IAAI,KAAA,CAAM,GAAG,CAAA,CAAE,KAAK,EAAE,CAAA;AAE/C,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,EAAK,CAAA,EAAA,EAAK;AAC5B,IAAA,MAAM,GAAA,GAAM,IAAI,CAAC,CAAA;AAGjB,IAAA,IAAI,IAAA,GAAO,CAAA;AACX,IAAA,IAAI,QAAQ,KAAA,CAAM,MAAA;AAElB,IAAA,OAAO,OAAO,KAAA,EAAO;AACnB,MAAA,MAAM,GAAA,GAAO,OAAO,KAAA,KAAW,CAAA;AAC/B,MAAA,IAAI,GAAA,CAAI,KAAA,CAAM,GAAG,CAAE,IAAK,GAAA,EAAK;AAC3B,QAAA,IAAA,GAAO,GAAA,GAAM,CAAA;AAAA,MACf,CAAA,MAAO;AACL,QAAA,KAAA,GAAQ,GAAA;AAAA,MACV;AAAA,IACF;AAGA,IAAA,IAAI,OAAO,CAAA,EAAG;AACZ,MAAA,MAAA,CAAO,CAAC,CAAA,GAAI,KAAA,CAAM,IAAA,GAAO,CAAC,CAAA;AAAA,IAC5B;AAEA,IAAA,IAAI,IAAA,KAAS,MAAM,MAAA,EAAQ;AACzB,MAAA,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,IACd,CAAA,MAAO;AACL,MAAA,KAAA,CAAM,IAAI,CAAA,GAAI,CAAA;AAAA,IAChB;AAAA,EACF;AAGA,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,IAAI,OAAA,GAAU,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA;AACpC,EAAA,OAAO,YAAY,EAAA,EAAI;AACrB,IAAA,MAAA,CAAO,KAAK,OAAO,CAAA;AACnB,IAAA,OAAA,GAAU,OAAO,OAAO,CAAA;AAAA,EAC1B;AAEA,EAAA,OAAO,OAAO,OAAA,EAAQ;AACxB","file":"index.mjs","sourcesContent":["/**\r\n * @lytjs/common-algorithm\r\n * 算法工具 - 最长递增子序列(LIS)\r\n */\r\n\r\n/**\r\n * 求最长递增子序列(Longest Increasing Subsequence)\r\n * 返回的是原数组中构成 LIS 的元素索引数组\r\n *\r\n * 算法: patience sorting + binary search\r\n * 时间复杂度:O(n log n)\r\n *\r\n * @param arr - 输入数组\r\n * @returns 构成 LIS 的索引数组\r\n */\r\nexport function getSequence<T extends string | number>(arr: Array<T>): number[] {\r\n const len = arr.length;\r\n if (len === 0) return [];\r\n\r\n // tails[i] 存储长度为 i+1 的 LIS 的最小末尾值的索引\r\n const tails: number[] = [];\r\n // parent[i] 存储 arr[i] 在 LIS 中的前驱索引\r\n const parent: number[] = new Array(len).fill(-1);\r\n\r\n for (let i = 0; i < len; i++) {\r\n const val = arr[i]!;\r\n\r\n // 二分查找:找到 tails 中第一个 >= val 的位置\r\n let left = 0;\r\n let right = tails.length;\r\n\r\n while (left < right) {\r\n const mid = (left + right) >>> 1;\r\n if (arr[tails[mid]!]! < val) {\r\n left = mid + 1;\r\n } else {\r\n right = mid;\r\n }\r\n }\r\n\r\n // left 就是 val 应该放置的位置\r\n if (left > 0) {\r\n parent[i] = tails[left - 1]!;\r\n }\r\n\r\n if (left === tails.length) {\r\n tails.push(i);\r\n } else {\r\n tails[left] = i;\r\n }\r\n }\r\n\r\n // 回溯构建 LIS 的索引序列\r\n const result: number[] = [];\r\n let current = tails[tails.length - 1]!;\r\n while (current !== -1) {\r\n result.push(current);\r\n current = parent[current]!;\r\n }\r\n\r\n return result.reverse();\r\n}\r\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";AAeO,SAAS,YAAuC,GAAA,EAAyB;AAC9E,EAAA,MAAM,MAAM,GAAA,CAAI,MAAA;AAChB,EAAA,IAAI,GAAA,KAAQ,CAAA,EAAG,OAAO,EAAC;AAGvB,EAAA,MAAM,QAAkB,EAAC;AAEzB,EAAA,MAAM,SAAmB,IAAI,KAAA,CAAM,GAAG,CAAA,CAAE,KAAK,EAAE,CAAA;AAE/C,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,EAAK,CAAA,EAAA,EAAK;AAC5B,IAAA,MAAM,GAAA,GAAM,IAAI,CAAC,CAAA;AAGjB,IAAA,IAAI,IAAA,GAAO,CAAA;AACX,IAAA,IAAI,QAAQ,KAAA,CAAM,MAAA;AAElB,IAAA,OAAO,OAAO,KAAA,EAAO;AACnB,MAAA,MAAM,GAAA,GAAO,OAAO,KAAA,KAAW,CAAA;AAC/B,MAAA,IAAI,GAAA,CAAI,KAAA,CAAM,GAAG,CAAE,IAAK,GAAA,EAAK;AAC3B,QAAA,IAAA,GAAO,GAAA,GAAM,CAAA;AAAA,MACf,CAAA,MAAO;AACL,QAAA,KAAA,GAAQ,GAAA;AAAA,MACV;AAAA,IACF;AAGA,IAAA,IAAI,OAAO,CAAA,EAAG;AACZ,MAAA,MAAA,CAAO,CAAC,CAAA,GAAI,KAAA,CAAM,IAAA,GAAO,CAAC,CAAA;AAAA,IAC5B;AAEA,IAAA,IAAI,IAAA,KAAS,MAAM,MAAA,EAAQ;AACzB,MAAA,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,IACd,CAAA,MAAO;AACL,MAAA,KAAA,CAAM,IAAI,CAAA,GAAI,CAAA;AAAA,IAChB;AAAA,EACF;AAGA,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,IAAI,OAAA,GAAU,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA;AACpC,EAAA,OAAO,YAAY,EAAA,EAAI;AACrB,IAAA,MAAA,CAAO,KAAK,OAAO,CAAA;AACnB,IAAA,OAAA,GAAU,OAAO,OAAO,CAAA;AAAA,EAC1B;AAEA,EAAA,OAAO,OAAO,OAAA,EAAQ;AACxB","file":"index.mjs","sourcesContent":["/**\n * @lytjs/common-algorithm\n * 算法工具 - 最长递增子序列(LIS)\n */\n\n/**\n * 求最长递增子序列(Longest Increasing Subsequence)\n * 返回的是原数组中构成 LIS 的元素索引数组\n *\n * 算法: patience sorting + binary search\n * 时间复杂度:O(n log n)\n *\n * @param arr - 输入数组\n * @returns 构成 LIS 的索引数组\n */\nexport function getSequence<T extends string | number>(arr: Array<T>): number[] {\n const len = arr.length;\n if (len === 0) return [];\n\n // tails[i] 存储长度为 i+1 的 LIS 的最小末尾值的索引\n const tails: number[] = [];\n // parent[i] 存储 arr[i] 在 LIS 中的前驱索引\n const parent: number[] = new Array(len).fill(-1);\n\n for (let i = 0; i < len; i++) {\n const val = arr[i]!;\n\n // 二分查找:找到 tails 中第一个 >= val 的位置\n let left = 0;\n let right = tails.length;\n\n while (left < right) {\n const mid = (left + right) >>> 1;\n if (arr[tails[mid]!]! < val) {\n left = mid + 1;\n } else {\n right = mid;\n }\n }\n\n // left 就是 val 应该放置的位置\n if (left > 0) {\n parent[i] = tails[left - 1]!;\n }\n\n if (left === tails.length) {\n tails.push(i);\n } else {\n tails[left] = i;\n }\n }\n\n // 回溯构建 LIS 的索引序列\n const result: number[] = [];\n let current = tails[tails.length - 1]!;\n while (current !== -1) {\n result.push(current);\n current = parent[current]!;\n }\n\n return result.reverse();\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lytjs/common-algorithm",
3
- "version": "6.4.0",
3
+ "version": "6.6.0",
4
4
  "description": "Algorithm utilities for LytJS",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
package/src/index.ts CHANGED
@@ -1,62 +1,62 @@
1
- /**
2
- * @lytjs/common-algorithm
3
- * 算法工具 - 最长递增子序列(LIS)
4
- */
5
-
6
- /**
7
- * 求最长递增子序列(Longest Increasing Subsequence)
8
- * 返回的是原数组中构成 LIS 的元素索引数组
9
- *
10
- * 算法: patience sorting + binary search
11
- * 时间复杂度:O(n log n)
12
- *
13
- * @param arr - 输入数组
14
- * @returns 构成 LIS 的索引数组
15
- */
16
- export function getSequence<T extends string | number>(arr: Array<T>): number[] {
17
- const len = arr.length;
18
- if (len === 0) return [];
19
-
20
- // tails[i] 存储长度为 i+1 的 LIS 的最小末尾值的索引
21
- const tails: number[] = [];
22
- // parent[i] 存储 arr[i] 在 LIS 中的前驱索引
23
- const parent: number[] = new Array(len).fill(-1);
24
-
25
- for (let i = 0; i < len; i++) {
26
- const val = arr[i]!;
27
-
28
- // 二分查找:找到 tails 中第一个 >= val 的位置
29
- let left = 0;
30
- let right = tails.length;
31
-
32
- while (left < right) {
33
- const mid = (left + right) >>> 1;
34
- if (arr[tails[mid]!]! < val) {
35
- left = mid + 1;
36
- } else {
37
- right = mid;
38
- }
39
- }
40
-
41
- // left 就是 val 应该放置的位置
42
- if (left > 0) {
43
- parent[i] = tails[left - 1]!;
44
- }
45
-
46
- if (left === tails.length) {
47
- tails.push(i);
48
- } else {
49
- tails[left] = i;
50
- }
51
- }
52
-
53
- // 回溯构建 LIS 的索引序列
54
- const result: number[] = [];
55
- let current = tails[tails.length - 1]!;
56
- while (current !== -1) {
57
- result.push(current);
58
- current = parent[current]!;
59
- }
60
-
61
- return result.reverse();
62
- }
1
+ /**
2
+ * @lytjs/common-algorithm
3
+ * 算法工具 - 最长递增子序列(LIS)
4
+ */
5
+
6
+ /**
7
+ * 求最长递增子序列(Longest Increasing Subsequence)
8
+ * 返回的是原数组中构成 LIS 的元素索引数组
9
+ *
10
+ * 算法: patience sorting + binary search
11
+ * 时间复杂度:O(n log n)
12
+ *
13
+ * @param arr - 输入数组
14
+ * @returns 构成 LIS 的索引数组
15
+ */
16
+ export function getSequence<T extends string | number>(arr: Array<T>): number[] {
17
+ const len = arr.length;
18
+ if (len === 0) return [];
19
+
20
+ // tails[i] 存储长度为 i+1 的 LIS 的最小末尾值的索引
21
+ const tails: number[] = [];
22
+ // parent[i] 存储 arr[i] 在 LIS 中的前驱索引
23
+ const parent: number[] = new Array(len).fill(-1);
24
+
25
+ for (let i = 0; i < len; i++) {
26
+ const val = arr[i]!;
27
+
28
+ // 二分查找:找到 tails 中第一个 >= val 的位置
29
+ let left = 0;
30
+ let right = tails.length;
31
+
32
+ while (left < right) {
33
+ const mid = (left + right) >>> 1;
34
+ if (arr[tails[mid]!]! < val) {
35
+ left = mid + 1;
36
+ } else {
37
+ right = mid;
38
+ }
39
+ }
40
+
41
+ // left 就是 val 应该放置的位置
42
+ if (left > 0) {
43
+ parent[i] = tails[left - 1]!;
44
+ }
45
+
46
+ if (left === tails.length) {
47
+ tails.push(i);
48
+ } else {
49
+ tails[left] = i;
50
+ }
51
+ }
52
+
53
+ // 回溯构建 LIS 的索引序列
54
+ const result: number[] = [];
55
+ let current = tails[tails.length - 1]!;
56
+ while (current !== -1) {
57
+ result.push(current);
58
+ current = parent[current]!;
59
+ }
60
+
61
+ return result.reverse();
62
+ }