您的位置:首页 > 其它

[Leetcode] bfs and dfs notes

2017-01-16 06:04 429 查看
DFS的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解,那就返回到上一个节点,然后从另一条路开始走到底。 
DFS适合此类题目:给定初始状态跟目标状态,要求判断从初始状态到目标状态是否有解。

深度优先搜索的缺点也出来了:难以寻找最优解,仅仅只能寻找有解。其优点就是内存消耗小,克服了刚刚说的广度优先搜索的缺点。

一种实现方法:

package questoins;

import java.util.*;

/**
* FULL REPO ADDRESS: https://github.com/hmny/interviewPrep/blob/LintCode/LintCodeSolutions/src/questoins/Puzzle_007.java * 1- bfs search
* 2- dfs search
* for the following tree
*/

/*
3
/ \
9  20
/  \
15   7
*/

public class Puzzle_007 {

/**
* this method creates the tree which is shown above and returns the root of that tree
*/
public TreeNode createSampleTree() {
TreeNode root = new TreeNode(3);
TreeNode a = new TreeNode(9);
TreeNode b = new TreeNode(20);
TreeNode c = new TreeNode(15);
TreeNode d = new TreeNode(7);
root.left = a;
root.right = b;
b.left = c;
b.right = d;
return root;
}

/**
* returns the left child if not visited, then right child if not visited
*/
private TreeNode getUnvisitedChildNode(TreeNode node) {
if (node.left != null) {
if (!node.left.visited) {
return node.left;
}
}
if (node.right != null) {
if (!node.right.visited) {
return  node.right;
}
}
return null;
}

public void serialize_using_bfs(TreeNode root) {
// BFS uses Queue
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
System.out.println(root.val);
while (!queue.isEmpty()) {
TreeNode node = queue.remove();  // remove the head of queue
TreeNode child = null;
while ((child = getUnvisitedChildNode(node)) != null) {
child.visited = true;
System.out.println(child.val);
queue.add(child);
}
}
}

public void serialize_using_dfs(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
root.visited = true;
System.out.println(root.val);
while (!stack.isEmpty()) {
TreeNode node = stack.peek();   // top of the stack without removing
TreeNode child = getUnvisitedChildNode(node);
if(child != null) {
child.visited = true;
System.out.println(child.val);
stack.push(child);
} else {
stack.pop();
}
}
}

private class TreeNode {
private int val;
private TreeNode left, right;
private boolean visited;
private TreeNode(int val) {
this.val = val;
this.left = this.right = null;
}

}
}


另一种方法:

图相关的问题主要集中在深度优先搜索(depth first search)和广度优先搜索(breath first search)。

下面是一个简单的图广度优先搜索的实现。

1) 定义GraphNode

class GraphNode{
int val;
GraphNode next;
GraphNode[] neighbors;
boolean visited;

GraphNode(int x) {
val = x;
}

GraphNode(int x, GraphNode[] n){
val = x;
neighbors = n;
}

public String toString(){
return "value: "+ this.val;
}
}

2) 定义一个队列Queue

class Queue{
GraphNode first, last;

public void enqueue(GraphNode n){
if(first == null){
first = n;
last = first;
}else{
last.next = n;
last = n;
}
}

public GraphNode dequeue(){
if(first == null){
return null;
}else{
GraphNode temp = new GraphNode(first.val, first.neighbors);
first = first.next;
return temp;
}
}
}

3) 用队列Queue实现广度优先搜索

public class GraphTest {

public static void main(String[] args) {
GraphNode n1 = new GraphNode(1);
GraphNode n2 = new GraphNode(2);
GraphNode n3 = new GraphNode(3);
GraphNode n4 = new GraphNode(4);
GraphNode n5 = new GraphNode(5);

n1.neighbors = new GraphNode[]{n2,n3,n5};
n2.neighbors = new GraphNode[]{n1,n4};
n3.neighbors = new GraphNode[]{n1,n4,n5};
n4.neighbors = new GraphNode[]{n2,n3,n5};
n5.neighbors = new GraphNode[]{n1,n3,n4};

breathFirstSearch(n1, 5);
}

public static void breathFirstSearch(GraphNode root, int x){
if(root.val == x)
System.out.println("find in root");

Queue queue = new Queue();
root.visited = true;
queue.enqueue(root);

while(queue.first != null){
GraphNode c = (GraphNode) queue.dequeue();
for(GraphNode n: c.neighbors){

if(!n.visited){
System.out.print(n + " ");
n.visited = true;
if(n.val == x)
System.out.println("Find "+n);
queue.enqueue(n);
}
}
}
}
}
value: 2 value: 3 value: 5 Find value: 5

value: 4

4000
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: