DFS算法可以被认为是回溯算法,BFS算法出现的场景:在一副图中找到从起点 start
到终点 target
的最近距离。比如两个单词通过替换某些字母,把其中一个变为另一个,每次只能替换一个字母。下面是BFS的算法伪代码:
int DFS(Node start, Node target){ Queue<Node> q; Set<Node> visited; q.offer(start); visited.add(start); int step=0; while (q not empty){ int sz=q.size(); for (int i;i<sz;i++){ Node cur=q.poll(); if (cur is target) return step; for (Node x: cur.adj()){ if (x not in visited){ q.offer(x); visited.add(x); } } } step++; } }
|
cur.adj
泛指与cur相邻的节点,整个代码可以描述成为了计算起点和终点的最近距离,从根节点开始遍历整个结构,使用队列q来存储每次的节点,step存储进行的步数。遍历的过程,将cur的相邻的点加入到队列里面, 如果达到了设置的终止条件,就返回,否则就继续step计数。
为什么要用队列存储?因为本质上树的节点,用linkedlist存储的。
二叉树的最小高度:
int minDepth(TreeNode root) { if (root == null) return 0; Queue<TreeNode> q = new LinkedList<>(); q.offer(root); int depth = 1; while (!q.isEmpty()) { int sz = q.size(); for (int i = 0; i < sz; i++) { TreeNode cur = q.poll(); if (cur.left == null && cur.right == null) return depth; if (cur.left != null) q.offer(cur.left); if (cur.right != null) q.offer(cur.right); } depth++; } return depth; }
|
解开密码锁的次数
int openLock(String[] deadends, String target) { Set<String> deads = new HashSet<>(); for (String s : deadends) deads.add(s); Set<String> visited = new HashSet<>(); Queue<String> q = new LinkedList<>(); int step = 0; q.offer("0000"); visited.add("0000"); while (!q.isEmpty()) { int sz = q.size(); for (int i = 0; i < sz; i++) { String cur = q.poll(); if (deads.contains(cur)) continue; if (cur.equals(target)) return step; for (int j = 0; j < 4; j++) { String up = plusOne(cur, j); if (!visited.contains(up)) { q.offer(up); visited.add(up); } String down = minusOne(cur, j); if (!visited.contains(down)) { q.offer(down); visited.add(down); } } } step++; } return -1; }
|
可以使用双向 BFS 算法来提高效率,代码稍加修改即可:
int openLock(String[] deadends, String target) { Set<String> deads = new HashSet<>(); for (String s : deadends) deads.add(s); Set<String> q1 = new HashSet<>(); Set<String> q2 = new HashSet<>(); Set<String> visited = new HashSet<>(); q1.add("0000"); q2.add(target); int step = 0; while (!q1.isEmpty() && !q2.isEmpty()) { Set<String> temp = new HashSet<>();
for (String cur : q1) { if (deads.contains(cur)) continue; if (q2.contains(cur)) return step; visited.add(cur);
for (int j = 0; j < 4; j++) { String up = plusOne(cur, j); if (!visited.contains(up)) temp.add(up); String down = minusOne(cur, j); if (!visited.contains(down)) temp.add(down); } } step++; q1 = q2; q2 = temp; } return -1; }
|