@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 +33 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +62 -62
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
|
package/dist/index.cjs.map
CHANGED
|
@@ -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":["/**\
|
|
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"]}
|
package/dist/index.mjs.map
CHANGED
|
@@ -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":["/**\
|
|
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
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
|
+
}
|