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

92 阅读1分钟

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

算法

889. 根据前序和后序遍历构造二叉树

题意理解

根据二叉树的前序遍历和后序遍历结果构造二叉树

思路

首先需要明确,要想从前序遍历和后续遍历构造二叉树,这颗二叉树必须每个节点至少有0个或者2个子节点,否则无法构造

  • 前序遍历的第一个元素,后序遍历的最后一个元素,都是根元素
  • 前序遍历的第二个元素为左子树的根节点
  • 找到左子树的根节点之后,通过判断后续遍历中左子树根节点的位置可以得到左子树的元素个数
  • 可以对前序遍历和后续遍历进行划分,通过递归求解

image.png

解题

const constructFromPrePost = (preorder, postorder) => {
  // 空树
  if (!preorder.length || !postorder.length) return null
  // 只有一个节点
  if (preorder.length === 1) return new TreeNode(preorder[0])

  const leftRootVal = preorder[1]
  const index = postorder.indexOf(leftRootVal) + 1
  const root = new TreeNode(preorder[0])

  root.left = constructFromPrePost(preorder.slice(1, index + 1), postorder.slice(0, index))
  root.right = constructFromPrePost(preorder.slice(index + 1), postorder.slice(index, postorder.length - 1))

  return root
}

实现 Type Flatten

实现一个 Flatten<T> 类型,将类型元组 T 扁平化后输出

type todo = ['a', ['b']]
type preview = Flatten<todo> // ['a', 'b']

思路

  • 遍历泛型 T 中的每个元素类型
  • 如果是元组类型,使用递归处理
  • 如果不是元组类型,保存这个类型

解题

type Pattern<T extends any[]> = T extends [infer R, ...infer U]
  ? R extends any[] ? [...Pattern<R>, ...Pattern<U>] : [R, ...Pattern<U>]
  : []