InorderTraversal
问题描述
实现二叉树中序遍历的类型版本。
举例:
const tree1 = {
val: 1,
left: null,
right: {
val: 2,
left: {
val: 3,
left: null,
right: null,
},
right: null,
},
} as const
type 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 const
const tree2 = {
val: 1,
left: null,
right: null
} as const
const tree3 = {
val: 1,
left: {
val: 2,
left: null,
right: null
},
right: null
} as const
const tree4 = {
val: 1,
left: null,
right: {
val: 2,
left: null,
right: null
}
} as const
type 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 选项即可。