

一、搜索和遍历
BFS 和 DFS 都是搜索的基础套路。它们常常出现在图和树里,写法上是遍历,目的上是找答案,所以很多时候也没必要把'遍历'和'搜索'分得太死。
BFS 是一层一层往外扩,先看离起点近的节点;DFS 则是沿着一条路尽量往深处走,走不动了再回头换路。前者更像按圈找,后者更像顺着岔路一路摸到底。

暴力搜索也离不开这两种思路。说白了,就是把所有情况都试一遍,靠枚举拿结果。题目规模小、没有明显优化空间时,这种办法很直接;代价也很明显,数据一大就容易跑不动。
二、回溯其实就是带剪枝的 DFS
回溯和 DFS 的关系没必要绕弯子,本质上就是 DFS。区别在于,回溯会更强调'试一下、走不通就退回来',然后继续尝试别的分支。
迷宫题很适合拿来理解这件事。沿着一条路往下走,走到死胡同时撤回上一个岔口,再换另一条路。提前知道某条路不可能得到答案时,直接丢掉,这一步就是剪枝。这个思路在题里用得非常多,尤其是搜索空间一大时,剪枝基本决定了能不能过。

三、几道典型题
3.1 计算布尔二叉树的值

这题的树是完整二叉树:要么没有节点,要么左右孩子都在。叶子节点存布尔值,非叶子节点存逻辑与或逻辑或。题目真正要做的事,就是把整棵树从下往上算出来。
我一般会把它看成后序遍历。先拿到左右子树的结果,再回到当前节点做合并。叶子节点是递归出口,直接返回当前值,不需要再往下看。代码也就顺着这个思路写,结构很短。

{
{
(root.left == ) {
root.val == ;
}
evaluateTree(root.left);
evaluateTree(root.right);
root.val == ? (left || right) : (left && right);
}
}











