图
问:
- dijkstra算法求最小路径
- 给定一个字符串数组,查询某字符串出现次数、以该字符串为前缀的字符串有多少。 解:
- 先假定一个目标节点与其他节点的距离无穷大并记录进哈希表,找到哈希表中距离最小的节点,然后遍历这个节点的所有边,如果通过这条路线使得目标到其他点的距离有小于哈希表中存的值,那么就更新哈希表中的数据。
function dijkstra(graph) {
const nodes = graph.nodes
// 随便选一个点作为观察对象
const targetNode = nodes[0]
const targetMap = new Map()
const edgesSet = new Set()
const choosedNode = new Set()
// 设定这个点到其他所有点的距离为无穷大
nodes.forEach((item) => {
targetMap.set(item, item === targetNode ? 0 : Infinity)
})
// 选取最小距离的节点
let minNode = getMinDisNode(targetMap, choosedSet)
while (minNode) {
const edges = minNode.edges
edges.forEach(item => {
// 排除重复边
if (!edgesSet.has(item)) {
edgesSet.add(item)
// 若target表记录的距离大于当前路线的距离,就更新target记录表
const oldDistance = targetMap.get(item.to)
const curDistance = item.weight + value
targetMap.set(item.to, Matn.min(oldDistance, curDistance))
choosedSet.add(minNode)
minNode = getMinDisNode(targetMap, choosedSet)
}
})
}
return targetMap
}
function getMinDisNode(targetMap, choosedSet) {
let minDis = Infinity
for (let [key, val] of targetMap.entries()) {
if (!choosedSet.has(key) && val < minDis) {
return key
}
}
return null
}
- 先生成一个root节点,遍历strArr中的每一个字符串,再遍历字符串的每一个字符,当前节点指向root节点,若当前节点没有遍历到的字符时,就给当前节点生成对应的字符节点,并记录该字符节点pass+1,当前节点指向新节点。若这个字符是字符串的最后一位,就给字符节点记录end+1。
const strArr = ['icytail', 'icy', 'tail', '哈哈', '哈呵']
// 字符串节点
class StrNode {
constructor() {
this.pass = 0
this.end = 0
this.charMap = new Map()
}
newCharNode (char) {
this.charMap.set(char, new StrNode())
}
isHasChar (char) {
return this.charMap.has(char)
}
getCharNode (char) {
return this.charMap.get(char)
}
}
function preTree(strArr) {
const rootNode = new StrNode()
for (let str of strArr) {
let curNode = rootNode
// 路过顶层节点次数+1,表明有多少个字符串进来过
curNode.pass += 1
for (let i = 0; i < str.length; i++) {
const char = str[i]
// 如果没有过这个字符
if (!curNode.isHasChar(char)) {
// 给当前节点创建一条新节点,并且cur指向这个新节点
curNode.newCharNode(char)
}
// 当前节点指向这个字符节点
curNode = curNode.getCharNode(char)
// 这个字符节点出现次数+1
curNode.pass += 1
// 如果是字符串结尾,那么该字符节点end+1
if (i === str.length - 1) curNode.end += 1
}
}
return rootNode
}
function searchCharPreNum(str, trie) {
let curNode = trie
let res = 0
for (let i = 0; i < str.length; i++) {
const char = str[i]
if (curNode.isHasChar(char)) {
curNode = curNode.getCharNode(char)
// 遍历到当前字符串的最后一位,那么pass值就是出现过多少次该字符串
if (i === str.length -1) res = curNode.pass
} else {
break
}
}
return res
}