算法小白,2024年2月21日,开始挑战在掘金发布“每日”系列。 (节假日可能会出门所以不算) 涉及到算法,type challenge 等,感兴趣的小伙伴可以持续关注督促互勉 🚀🚀🚀
算法
题意理解
根据给出的数据结构构造一棵树,统计树中合法的路径,路径中只有一个质数的被视为合法路径
思路
- 实现一个方法用来判断输入参数是否是质数
- 根据入参构造树结构
- 遍历节点,跳过非质数节点
- 对质数节点,遍历其相邻节点,过滤掉为质数的相邻节点
- 统计不为质数的相邻节点...
- 思路断了
挑战失败 ... 没想到怎么实现统计相邻节点,去除重复值
官方题解
const countPaths = (n, edges) => {
// 构造图
const graph = new Array(n + 1).fill("").map(() => [])
for (const [i, j] of edges) {
graph[i].push(j)
graph[j].push(i)
}
// 递归判断相邻节点
const dfs = (i, pre) => {
seen.push(i)
for (const j of graph[i]) {
if (j !== pre && !isPrime(j)) {
dfs(j, i)
}
}
}
let res = 0
let seen = []
let count = new Array(n + 1).fill(0)
for (let i = 1; i <= n; i++) {
if (!isPrime(i)) continue
let cur = 0
for (const j of graph[i]) {
if (isPrime(j)) continue
if (count[j] === 0) {
seen = []
dfs(j, 0)
let cnt = seen.length
for (const k of seen) {
count[k] = cnt
}
}
res += count[j] * cur
cur += count[j]
}
res += cur
}
return res
}
// 是否是质数
const isPrime = (num) => {
if (num < 2) return false
for (let i = 2; i <= Math.sqrt(num); i++) {
if (num % i === 0) return false
}
return true
}
TypeChallenge
实现类型 StringToUnion<S>,实现字符串类型的字母拆分成字母联合类型
type todo = 'abc'
type preview = StringToUnion<todo> // 'a' | 'b' | 'c'
思路
- 类型推导 + 模板字符串 + 递归
- 或者先拆分成元组类型,再元组转联合类型
type StringToUnion<S extends string> = S extends `${infer R}${infer L}`
? R | StringToUnion<L>
: never
type StringToUnion<T extends string, R extends stirng[] = []> =
T extends `${infer S}${infer E}`
? StringToUnion<E, [...R, S]>
: R[number]