Depth-First Search
Tree O(n \* m)
Link to heading
Traverse by Orders Link to heading
dfs(root) {
// preorder
dfs(root.left)
// inorder
dfs(root.right)
// postorder
}
1
/ \
2 3
/ \ / \
4 5 6 7
- Preorder traversal: root, left, right:
1245367
- Inorder traversal: left root right:
4251637
- Postorder traversal: left, right, root:
4526731
- 大部分时候是 void inorder(), preorder(), postorder()
🌟🌟🌟🌟 Preorder
114 - 反着做 preorder 430 - Flatten DoublyLinkedList, (OR 普通的 while loop) 437 - 用 Map 记录 value, 类似 prefix sum
🌟🌟 Inorder
285 - Tree 快慢指针 426 - Tree 转成 Sorted Doubly LinkedList 510 - 285 增强, 画图 & while loop 反推 (左中右 -> 右中左)
🌟🌟🌟🌟 Postorder
449 - Tree (De)serialization, Stack, dfs
🌟🌟🌟🌟 Mix
105 - serialize from preorder & inorder 106 - serialize from postorder & inorder
基于 Traverse Orders, 更实用的 useage Link to heading
dfs(res, root, value) {
if (!root):
return
if (value = root.val):
res.add(root)
return
for option : options:
做选择
dfs(res, newRoot, newValue)
撤销选择
}
步骤
- base case: if root == null
- inductive case: if can make recursive call
- return
Helper functions
- depth(), isBST(), nodeCount(), dfs()
- 讲究 order 时 (一般用 PostOrder 方式)
- dfs() return TreeNode
- 根据 returned left & right 判断
⭐️⭐️⭐️ Tree
333 - 经典 DFS, recursive main & recursive helper function 124 - ❤️ res 不一定是 leaf -> leaf path 236 - ❤️ 三选一 return left, right, root 250 - ❤️ helper return bool 判定 univalue subtree 1650 - ❤️ helper return bool (另一个逻辑: set)
其他不同的格式 O(2^N) 每个元素用一次, 每个元素只有两种选择 Link to heading
逻辑相似 (e.g. Permutation - 找到所有可能性) Link to heading
helper function 必不可少
dfs(所有选项, 当前 index, res, cur)
index 注意:
- base case & recursive call 中的 index 判定:
Value | Index
- base case & recursive call 中的 index 判定:
步骤
- base case: index 或者 cur 达到上限
- inductive:
- recursive call with new index & cur
cur.add() + dfs(...) + cur.remove()
- 如果是更改 input, 需要快慢指针 swap 来代替 cur 和 res
- dfs()/main()中可以加 set 来防重
- 取决于题型: 前后 add + remove, 或者设定 true / false
- 取决于题型: set 保存 value 还是 index
防重
// 1. 如果Traverse strategy每次从index开始, 必须要sort Arrays.sort(num) // 2. 当前**traverse**中, 不能重复使用某元素 if (visitedIndex.contains(i)) { continue; } // 3. 当前**level**中, 不能以相同数值做起点 (用nums[i] == nums[i-1]代替set) Set<Integer> visitedValue = new HashSet<>(); for (i from x to y) { if (visitedValue.contains(nums[i])) { continue; } visitedValue.add(nums[i]); }
⭐️ 防重 47 - for loop 起点为 0 90 - for loop 起点为 index 526 - 用 boolean list 整体防重
⭐️⭐️ Matrix: BFS / DFS 都可以
79 419 547 694
⭐️⭐️⭐️ 灵活运用 17 51 93 131 - traverse 所有组合, 每个组成的 substring 检查是不是 palindrome 216