挑战 - 每日系列(Algorithm + TypeChallenge)

91 阅读2分钟

算法小白,2024年2月21日,开始挑战在掘金发布“每日”系列。 (节假日可能会出门所以不算) 涉及到算法,type challenge 等,感兴趣的小伙伴可以持续关注督促互勉 🚀🚀🚀

算法

2673. 使二叉树所有路径值相等的最小代价

题意理解

对于一棵完全二叉树,使每个叶子节点到跟节点的值相同,每次只能增加一个节点值 +1,求最小操作数

思路

  • 统计所有叶子节点的值,求出最大值
  • 求出每条路径的差值
  • 不足的叶子节点需要添加值,但是同时也可以增加其父节点的值,这里不是很好处理,说明思路有问题

贪心:

  • 对于同一个父节点的相邻子节点,只需要补齐差值即可
  • 对于不同父节点的相邻节点,只需要修改父节点的差值即可
  • 使所有相同父节点的叶子节点补其差值
  • 遍历所有的父节点,只需要求得补齐差值需要的步数即可

解题

const minIncrements = (n, cost) => {
  let res = 0
  // 从第一个非叶子节点开始处理,叶子节点从0开始标记
  for (let i = Math.floor(n / 2) - 1; i >= 0; i--) {
    // 需要对叶子节点操作的次数
    res += Math.abs(cost[2 * i + 1] - cost[2 * i + 2])
    // 跟新当前节点的值
    cost[i] += Math.max(cost[2 * i + 1], cost[2 * i + 2])
  }
  return res
}

TypeChallenge

实现类型 Merge<T, S>,合并两个类型,如果有重复则 S 覆盖掉 T 中重复的类型键名

思路

  • 使用 &链接两个类型(结果重复的类型会变成 never)
  • 遍历 T 和 S 的 keys
  • 如果 key 存在于 S 中,则使用 S 的类型
  • 不存在则判断是否存在 T 中,存在则使用 T 的类型

解题

type Merge<S, T> = {
  [key in keyof S | keyof T]: key extends keyof S
     ? S[key]
     : key extends keyof T
       ? T[key]
       : never
}