arayts
Version:
让 TypeScript 开发如丝般顺滑。ArayTS 提供了一套高效、优雅的算法工具集,包含常用的数据结构与算法实现,帮助开发者轻松构建可靠的应用程序。
384 lines (383 loc) • 11.3 kB
JavaScript
"use strict";
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.topologicalSort = exports.Trie = exports.kmp = exports.treeTraversal = exports.TreeNode = exports.UnionFind = exports.binarySearch = exports.quickSort = exports.levenshteinDistance = exports.longestCommonSubsequence = exports.shuffle = exports.LRUCache = exports.memoize = void 0;
/**
* 函数记忆化
* @param fn 需要缓存的函数
*/
var memoize = function (fn) {
var cache = new Map();
return function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}
var result = fn.apply(void 0, args);
cache.set(key, result);
return result;
};
};
exports.memoize = memoize;
/**
* LRU缓存
*/
var LRUCache = /** @class */ (function () {
function LRUCache(capacity) {
this.capacity = capacity;
this.cache = new Map();
}
LRUCache.prototype.get = function (key) {
if (!this.cache.has(key))
return undefined;
var value = this.cache.get(key);
this.cache.delete(key);
this.cache.set(key, value);
return value;
};
LRUCache.prototype.put = function (key, value) {
if (this.cache.has(key)) {
this.cache.delete(key);
}
else if (this.cache.size >= this.capacity) {
var firstKey = this.cache.keys().next().value;
this.cache.delete(firstKey);
}
this.cache.set(key, value);
};
return LRUCache;
}());
exports.LRUCache = LRUCache;
/**
* 洗牌算法
*/
var shuffle = function (arr) {
var _a;
var result = __spreadArray([], arr, true);
for (var i = result.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
_a = [result[j], result[i]], result[i] = _a[0], result[j] = _a[1];
}
return result;
};
exports.shuffle = shuffle;
/**
* 最长公共子序列
*/
var longestCommonSubsequence = function (text1, text2) {
var dp = Array(text1.length + 1)
.fill(0)
.map(function () { return Array(text2.length + 1).fill(0); });
for (var i = 1; i <= text1.length; i++) {
for (var j = 1; j <= text2.length; j++) {
if (text1[i - 1] === text2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
}
else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
return dp[text1.length][text2.length];
};
exports.longestCommonSubsequence = longestCommonSubsequence;
/**
* 最短编辑距离(Levenshtein Distance)
*/
var levenshteinDistance = function (str1, str2) {
var dp = Array(str1.length + 1)
.fill(0)
.map(function () { return Array(str2.length + 1).fill(0); });
for (var i = 0; i <= str1.length; i++)
dp[i][0] = i;
for (var j = 0; j <= str2.length; j++)
dp[0][j] = j;
for (var i = 1; i <= str1.length; i++) {
for (var j = 1; j <= str2.length; j++) {
if (str1[i - 1] === str2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1];
}
else {
dp[i][j] = Math.min(dp[i - 1][j] + 1, // 删除
dp[i][j - 1] + 1, // 插入
dp[i - 1][j - 1] + 1 // 替换
);
}
}
}
return dp[str1.length][str2.length];
};
exports.levenshteinDistance = levenshteinDistance;
/**
* 快速排序
*/
var quickSort = function (arr) {
if (arr.length <= 1)
return arr;
var swap = function (array, i, j) {
var _a;
_a = [array[j], array[i]], array[i] = _a[0], array[j] = _a[1];
};
var partition = function (array, low, high) {
var pivot = array[high]; // 使用数组最后一个元素作为基准值
var i = low - 1;
for (var j = low; j < high; j++) {
if (array[j] <= pivot) {
i++;
swap(array, i, j);
}
}
swap(array, i + 1, high);
return i + 1;
};
var quickSortHelper = function (array, low, high) {
if (low < high) {
var pivotIndex = partition(array, low, high);
quickSortHelper(array, low, pivotIndex - 1); // 左侧子数组
quickSortHelper(array, pivotIndex + 1, high); // 右侧子数组
}
};
var arrCopy = __spreadArray([], arr, true); // 避免修改原数组
quickSortHelper(arrCopy, 0, arrCopy.length - 1);
return arrCopy;
};
exports.quickSort = quickSort;
/**
* 二分查找
* @returns 目标值的索引,未找到返回-1
*/
var binarySearch = function (arr, target) {
var left = 0;
var right = arr.length - 1;
while (left <= right) {
var mid = Math.floor((left + right) / 2);
if (arr[mid] === target)
return mid;
if (arr[mid] < target)
left = mid + 1;
else
right = mid - 1;
}
return -1;
};
exports.binarySearch = binarySearch;
/**
* 并查集
*/
var UnionFind = /** @class */ (function () {
function UnionFind(size) {
this.parent = Array.from({ length: size }, function (_, i) { return i; });
this.rank = Array(size).fill(0);
}
UnionFind.prototype.find = function (x) {
if (this.parent[x] !== x) {
this.parent[x] = this.find(this.parent[x]);
}
return this.parent[x];
};
UnionFind.prototype.union = function (x, y) {
var rootX = this.find(x);
var rootY = this.find(y);
if (rootX !== rootY) {
if (this.rank[rootX] < this.rank[rootY]) {
this.parent[rootX] = rootY;
}
else if (this.rank[rootX] > this.rank[rootY]) {
this.parent[rootY] = rootX;
}
else {
this.parent[rootY] = rootX;
this.rank[rootX]++;
}
}
};
UnionFind.prototype.connected = function (x, y) {
return this.find(x) === this.find(y);
};
return UnionFind;
}());
exports.UnionFind = UnionFind;
/**
* 二叉树节点
*/
var TreeNode = /** @class */ (function () {
function TreeNode(value, left, right) {
if (left === void 0) { left = null; }
if (right === void 0) { right = null; }
this.value = value;
this.left = left;
this.right = right;
}
return TreeNode;
}());
exports.TreeNode = TreeNode;
/**
* 二叉树遍历
*/
exports.treeTraversal = {
preorder: function (root) {
var result = [];
var traverse = function (node) {
if (!node)
return;
result.push(node.value);
traverse(node.left);
traverse(node.right);
};
traverse(root);
return result;
},
inorder: function (root) {
var result = [];
var traverse = function (node) {
if (!node)
return;
traverse(node.left);
result.push(node.value);
traverse(node.right);
};
traverse(root);
return result;
},
postorder: function (root) {
var result = [];
var traverse = function (node) {
if (!node)
return;
traverse(node.left);
traverse(node.right);
result.push(node.value);
};
traverse(root);
return result;
}
};
/**
* KMP字符串匹配
* @returns 模式串在文本串中的起始位置,未找到返回-1
*/
var kmp = function (text, pattern) {
if (pattern.length === 0)
return 0;
// 构建next数组
var next = [0];
for (var i = 1, j = 0; i < pattern.length; i++) {
while (j > 0 && pattern[i] !== pattern[j]) {
j = next[j - 1];
}
if (pattern[i] === pattern[j]) {
j++;
}
next[i] = j;
}
// 匹配
for (var i = 0, j = 0; i < text.length; i++) {
while (j > 0 && text[i] !== pattern[j]) {
j = next[j - 1];
}
if (text[i] === pattern[j]) {
j++;
}
if (j === pattern.length) {
return i - j + 1;
}
}
return -1;
};
exports.kmp = kmp;
/**
* Trie(前缀树)
*/
var Trie = /** @class */ (function () {
function Trie() {
this.root = {};
}
Trie.prototype.insert = function (word) {
var node = this.root;
for (var _i = 0, word_1 = word; _i < word_1.length; _i++) {
var char = word_1[_i];
if (!node[char]) {
node[char] = {};
}
node = node[char];
}
node.isEnd = true;
};
Trie.prototype.search = function (word) {
var node = this.traverse(word);
return node !== null && node.isEnd === true;
};
Trie.prototype.startsWith = function (prefix) {
return this.traverse(prefix) !== null;
};
Trie.prototype.traverse = function (str) {
var node = this.root;
for (var _i = 0, str_1 = str; _i < str_1.length; _i++) {
var char = str_1[_i];
if (!node[char]) {
return null;
}
node = node[char];
}
return node;
};
return Trie;
}());
exports.Trie = Trie;
/**
* 拓扑排序(Kahn算法)
* @param graph 邻接表表示的有向图
* @returns 拓扑排序结果,如果存在环则返回空数组
*/
var topologicalSort = function (graph) {
var inDegree = new Map();
var result = [];
var queue = [];
// 初始化入度
// 使用 Array.from() 遍历 Map
Array.from(graph.entries()).forEach(function (_a) {
var node = _a[0], neighbors = _a[1];
if (!inDegree.has(node)) {
inDegree.set(node, 0);
}
neighbors.forEach(function (neighbor) {
inDegree.set(neighbor, (inDegree.get(neighbor) || 0) + 1);
});
});
// 将入度为0的节点加入队列
// 使用 Array.from() 将 Map 转换为数组进行遍历
Array.from(inDegree.entries()).forEach(function (_a) {
var node = _a[0], degree = _a[1];
if (degree === 0) {
queue.push(node);
}
});
// BFS
while (queue.length > 0) {
var node = queue.shift();
result.push(node);
if (graph.has(node)) {
for (var _i = 0, _a = graph.get(node); _i < _a.length; _i++) {
var neighbor = _a[_i];
inDegree.set(neighbor, inDegree.get(neighbor) - 1);
if (inDegree.get(neighbor) === 0) {
queue.push(neighbor);
}
}
}
}
return result.length === inDegree.size ? result : [];
};
exports.topologicalSort = topologicalSort;