您的位置:首页 > 编程语言 > Java开发

java常用算法之字梯(广度优先搜索bfs)

2016-02-16 17:17 507 查看
<span style="font-family: 'microsoft yahei', simhei, arial, sans-serif; font-size: 16px;">给定2个单词(start</span><span style="font-family: 'microsoft yahei', simhei, arial, sans-serif; font-size: 16px;">和end),和一个字典,找到最短的变换序列的长度,从start到end,这样的一次</span><span style="font-size: 16px; font-family: 'microsoft yahei', simhei, arial, sans-serif;">只有一个字母可以改变并且</span><span style="font-size: 16px; font-family: 'microsoft yahei', simhei, arial, sans-serif;">每个中间字必须存在于字典。例如,给定:</span><pre style="margin: 0px 0em 25px; padding: 8px; border: 1px solid rgb(209, 209, 232); font-size: 13px; border-radius: 4px; color: rgb(34, 34, 34); line-height: 25.5px; background-color: rgb(250, 248, 227);">start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]<span style="font-family: 'microsoft yahei', simhei, arial, sans-serif; font-size: 16px;"> </span>


<span style="font-family: 'microsoft yahei', simhei, arial, sans-serif; font-size: 16px;"> 程序将会找到"hit" -> "hot" -> "dot" -> "dog" -> "cog",输出最短变换距离4</span>
package utils;

import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;

import com.google.gson.Gson;

public class WordLadder {

// solution function
public static int ladderLength(String start, String end,
HashSet<String> dict) {
// saving the graph nodes on hash map.
HashMap<String, GraphNode> nodes = new HashMap<>();
// adding the start and the end words to the dict
dict.add(start);
dict.add(end);
for (String word : dict) {
nodes.put(word, new GraphNode(word));
}
// update each node's adjacents according to one character different
// relation
Object[] dictArray = dict.toArray();
for (int i = 0; i < dictArray.length; i++) {
for (int j = i + 1; j < dictArray.length; j++) {
if (isNeighbor((String) dictArray[i], (String) dictArray[j])) {
nodes.get((String) dictArray[i]).childs.add(nodes
.get((String) dictArray[j]));
nodes.get((String) dictArray[j]).childs.add(nodes
.get((String) dictArray[i]));
}
}
}

// Run BFS on the Graph and take the dist generated as result
HashMap<String, Integer> result = BFS(nodes, start);

// Return the distance of the end word node from the start word node
return result.get(end);

}

// BFS function
public static HashMap<String, Integer> BFS(
HashMap<String, GraphNode> nodes, String start) {

HashMap<String, Integer> visited = new HashMap<>();
HashMap<String, Integer> dist = new HashMap<>();
for (String key : nodes.keySet()) {
visited.put(key, 0);
dist.put(key, 0);
}
Queue<String> q = new LinkedList<>();
q.add(start);
visited.put(start, 1);
while (!q.isEmpty()) {
String dequeued = q.remove();
GraphNode curNode = nodes.get(dequeued);
LinkedList<GraphNode> currAdjs = curNode.childs;
for (int i = 0; i < currAdjs.size(); i++) {
GraphNode adj = (GraphNode) currAdjs.get(i);
if (visited.get(adj.word) == 0) {
visited.put(adj.word, 1);
dist.put(adj.word, dist.get(dequeued) + 1);
q.add(adj.word);
}

}
}
return dist;

}

// check if two words differ by one character
public static boolean isNeighbor(String a, String b) {
assert a.length() == b.length();
int differ = 0;
for (int i = 0; i < a.length(); i++) {
if (a.charAt(i) != b.charAt(i))
differ++;
if (differ > 1)
return false;
}
return true;
}

public static void main(String[] args) {
// dict = ["hot","dot","dog","lot","log"] result 5;
HashSet<String> dict = new HashSet<String>();
dict.add("hot");
dict.add("dot");
dict.add("dog");
dict.add("lot");
dict.add("log");
System.out.println(ladderLength("hit", "cog", dict));
}

}

class GraphNode {
String word;
LinkedList<GraphNode> childs;

public GraphNode(String word) {
this.word = word;
childs = new LinkedList<GraphNode>();
}

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