type-challenges:InorderTraversal

41 阅读1分钟

InorderTraversal

问题描述

实现二叉树中序遍历的类型版本。

举例:

const tree1 = {
  val: 1,
  left: null,
  right: {
    val: 2,
    left: {
      val: 3,
      left: null,
      right: null,
    },
    right: null,
  },
} as consttype A = InorderTraversal<typeof tree1> // [1, 3, 2]

二叉树的前中后序遍历有个简单的方式记忆,详情看这个视频 【纯干货】三分钟教会你遍历二叉树!学不会举报我!!

// ============= Test Cases =============
import type { Equal, Expect } from './test-utils'const tree1 = {
  val: 1,
  left: null,
  right: {
    val: 2,
    left: {
      val: 3,
      left: null,
      right: null
    },
    right: null
  }
} as constconst tree2 = {
  val: 1,
  left: null,
  right: null
} as constconst tree3 = {
  val: 1,
  left: {
    val: 2,
    left: null,
    right: null
  },
  right: null
} as constconst tree4 = {
  val: 1,
  left: null,
  right: {
    val: 2,
    left: null,
    right: null
  }
} as consttype cases = [
  Expect<Equal<InorderTraversal<null>, []>>,
  Expect<Equal<InorderTraversal<typeof tree1>, [1, 3, 2]>>,
  Expect<Equal<InorderTraversal<typeof tree2>, [1]>>,
  Expect<Equal<InorderTraversal<typeof tree3>, [2, 1]>>,
  Expect<Equal<InorderTraversal<typeof tree4>, [1, 2]>>
]
​
// ============= Your Code Here =============
interface TreeNode {
  val: number
  left: TreeNode | null
  right: TreeNode | null
}
// 答案1
type InorderTraversal<T extends TreeNode | null, NT extends TreeNode = NonNullable<T>> = T extends null
  ? []
  : [...InorderTraversal<NT['left']>, NT['val'], ...InorderTraversal<NT['right']>]
  
// 答案2
type InorderTraversal<T extends TreeNode | null> = T extends TreeNode
  ? [...InorderTraversal<T['left']>, T['val'], ...InorderTraversal<T['right']>]
  : []
​
// 错误答案
type InorderTraversal<T extends TreeNode | null> = T extends null
  ? []
  : [...InOrderTraversal<T['left']>, T['val'], ...InOrderTraversal<T['right']>]
​
​

中序遍历需要先判断有无左节点,之后才是当前节点,最后是右节点。

在错误答案中, 泛型约束 T extends TreeNode | null 这里,如果 T 就是联合类型 TreeNode | null ,那么 T extends null 将会为 false,所以 T['left'],T['right'] 可能不存在。所以这里需要排除 null ,如答案1。答案2是同一个意思,排除 null 选项即可。