回溯算法
回溯算法处理 5w 条数据优化
❓:我想根据当前节点 id 回溯出他的路径层级扁平数组
💡:
interface TreeNode {
id: string;
parentId: string | null;
name: string;
}
const getNodePath = (tree: TreeNode[], nodeId: string): TreeNode[] => {
const node = tree.find((item) => item.id === nodeId);
if (!node) return [];
if (node.parentId === null) {
return [node];
}
const parentNode = tree.find((item) => item.id === node.parentId);
if (!parentNode) return [];
const parentPath = getNodePath(tree, parentNode.id);
return [...parentPath, node];
};
在上述代码中,getNodePath 函数接收一个树形结构的数组 tree 和当前节点的 IDnodeId 作为参数。首先,通过 tree.find()方法找到当前节点 node。如果节点不存在,则直接返回一个空数组。
接下来,判断当前节点的 parentId 属性。如果为 null,表示当前节点是根节点,直接将其作为路径的起点,返回一个只包含当前节点的数组。
如果 parentId 不为 null,则继续递归调用 getNodePath 函数,传入当前节点的 parentId 作为新的 nodeId。通过递归回溯,我们可以获取到父节点的路径。
最后,将父节点的路径 parentPath 与当前节点 node 合并为一个新的数组,并返回该数组作为当前节点的路径层级扁平数组。
你按照以下方式调用 getNodePath 函数:
const tree: TreeNode[] = [
{ id: "1", parentId: null, name: "Root" },
{ id: "2", parentId: "1", name: "Node 1" },
{ id: "3", parentId: "2", name: "Node 1.1" },
{ id: "4", parentId: "3", name: "Node 1.1.1" },
];
const nodeId = "4";
const nodePath = getNodePath(tree, nodeId);
console.log(nodePath);
输出结果为:
[
{ id: "1", parentId: null, name: "Root" },
{ id: "2", parentId: "1", name: "Node 1" },
{ id: "3", parentId: "2", name: "Node 1.1" },
{ id: "4", parentId: "3", name: "Node 1.1.1" },
];
❓:回溯算法还有优化的空间吗
💡:在上述实现中,回溯算法的时间复杂度为 O(n^2),其中 n 是树的节点数量。这是因为在每个节点的回溯过程中,都需要遍历整个树来查找父节点。
我们可以使用哈希表来优化回溯算法的性能。将树的节点存储在哈希表中,以节点的 ID 作为键,节点本身作为值。这样,在每个节点的回溯过程中,我们可以通过节点的父节点 ID 直接从哈希表中获取父节点,而不需要遍历整个树。
以下是使用哈希表进行优化的示例代码:
interface TreeNode {
id: string;
parentId: string | null;
name: string;
}
const getNodePath = (tree: TreeNode[], nodeId: string): TreeNode[] => {
const nodeMap = new Map<string, TreeNode>();
// 构建哈希表
for (const node of tree) {
nodeMap.set(node.id, node);
}
const node = nodeMap.get(nodeId);
if (!node) return [];
if (node.parentId === null) {
return [node];
}
const parentPath = getNodePath(tree, node.parentId);
return [...parentPath, node];
};
在上述代码中,我们首先创建了一个空的 Map 对象 nodeMap,用于存储树的节点。
接下来,在构建哈希表阶段,我们遍历树的节点,并将节点的 ID 作为键,节点本身作为值,存储在 nodeMap 中。
在回溯阶段我们可以通过节点的 ID 直接从 nodeMap 中获取节点的父节点,而不需要遍历整个树来查找。
使用哈希表进行优化后,回溯算法的时间复杂度为 O(n),其中 n 是树的节点数量。这是因为在回溯过程中,每个节点的父节点都可以在 O(1) 的时间内获取到。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理