来源庞果英雄会的挑战题
此题是个图论问题,把A,B与dict里的所有字符串看成图的顶点
求每个顶点的邻接矩阵。
举例如下
根据每个顶点的邻接矩阵组成图
然后求图中的最小路径
得到start节点到图中每一节点的最小路径数组path
然后看这个path数组中path[indexOf(end)]是否为Integer.MAX_VALUE
如果是,那么没有从start到end的路径,返回空集
如果否,输出所有通路。
在记录最短路径上的图顶点的时候有一个小技巧
最短路径可能有多条,因此在记录最短路径经过节点上应用了
这样就把多条最短路径的节点都记录下来
然后这个矩阵又组成了新图,这个新图上的所有路径都是最短路径
DFS输出就是最终答案
最新进展,提交错误的原因是我把题目原有的import删掉了一部分。
由于此题只有一次挑战机会,所以不得已又注册了一个账号,重新提交了一次。结果是挑战成功
此题是个图论问题,把A,B与dict里的所有字符串看成图的顶点
求每个顶点的邻接矩阵。
举例如下
"hot"的邻接矩阵为
[hit, null, null, null, null, lot, dot]
根据每个顶点的邻接矩阵组成图
然后求图中的最小路径
得到start节点到图中每一节点的最小路径数组path
然后看这个path数组中path[indexOf(end)]是否为Integer.MAX_VALUE
如果是,那么没有从start到end的路径,返回空集
如果否,输出所有通路。
在记录最短路径上的图顶点的时候有一个小技巧
最短路径可能有多条,因此在记录最短路径经过节点上应用了
int[][] previous = new int[d.length][d.length];并初始化为-1
previous[index][temp_index] = temp_index;
这样就把多条最短路径的节点都记录下来
然后这个矩阵又组成了新图,这个新图上的所有路径都是最短路径
DFS输出就是最终答案
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Vector;
/**
* @author chenby@edgesoft.cn
* @since 2013-10-30
* @version
* @see
*/
public class Main {
/**
*
* @param args
*/
public static void main(String[] args) {
Set<String> sets = new HashSet<String>();
sets.add("hot");
sets.add("dot");
sets.add("dog");
sets.add("lot");
sets.add("log");
Vector<Vector<String>> rs = new Main().findLadders("hit", "cog", sets);
System.out.println(rs);
sets = new HashSet<String>();
sets.add("amn");
sets.add("a2n");
sets.add("b2b");
sets.add("bhb");
sets.add("b2n");
sets.add("ahn");
rs = new Main().findLadders("a2b", "bmn", sets);
System.out.println(rs);
}
public Vector<Vector<String>> findLadders(String start, String end, Set<String> dict) {
Vector<Vector<String>> vector = new Vector<Vector<String>>();
if (start.equals(end)) {
return vector;
}
String[] d = init_dict(start, end, dict);
List<String> queue = new ArrayList<String>();
boolean[] visable = new boolean[d.length];
int[][] previous = new int[d.length][d.length];
for (int i = 0; i < previous.length; i++) {
for (int j = 0; j < previous[i].length; j++) {
previous[i][j] = -1;
}
}
int[] path = new int[d.length];
for (int i = 0; i < path.length; i++) {
path[i] = Integer.MAX_VALUE;
}
queue.add(start);
path[indexOf(start, d)] = 0;
visable[indexOf(start, d)] = true;
while (!queue.isEmpty()) {
String temp = queue.get(0);
queue.remove(0);
int temp_index = indexOf(temp, d);
String[] adj = getadj(temp, d);
for (int i = 0; i < adj.length; i++) {
String str = adj[i];
if (str != null) {
int index = indexOf(str, d);
if (!visable[index] && path[index] >= path[temp_index] + 1) {
path[index] = path[temp_index] + 1;
previous[index][temp_index] = temp_index;
}
}
}
int min_path = Integer.MAX_VALUE;
int min_index = -1;
for (int i = 0; i < d.length; i++) {
if (!visable[i]) {
if (path[i] < min_path) {
min_path = path[i];
min_index = i;
}
}
}
if (min_index != -1 && !visable[min_index]) {
visable[min_index] = true;
queue.add(d[min_index]);
}
}
if (path[1] == Integer.MAX_VALUE) {
//no path
return vector;
}
dfs(1, previous, d, path[1] + 1, vector);
return vector;
}
private void dfs(int index, int[][] previous, String[] dict, int len, Vector<Vector<String>> vector) {
String[] path = new String[len];
printPaths(1, previous, path, 0, dict, vector);
}
private void printPaths(int index, int[][] previous, String[] path, int n, String[] dict,
Vector<Vector<String>> vector) {
path[n++] = dict[index];
if (index == 0) {
Vector<String> line = new Vector<String>();
for (int i = path.length - 1; i >= 0; i--) {
line.add(path[i]);
}
vector.add(line);
}
else {
List<Integer> adj = getadj(index, previous);
for (int i = 0; i < adj.size(); i++) {
printPaths(adj.get(i), previous, path, n, dict, vector);
}
}
}
private List<Integer> getadj(int index, int[][] previous) {
List<Integer> rs = new ArrayList<Integer>();
for (int i = 0; i < previous[index].length; i++) {
if (previous[index][i] != -1) {
rs.add(previous[index][i]);
}
}
return rs;
}
private String[] init_dict(String a, String b, Set<String> d) {
String[] dict = new String[d.size() + 2];
int i = 2;
for (Iterator<String> iterator = d.iterator(); iterator.hasNext();) {
dict[i++] = iterator.next();
}
dict[0] = a;
dict[1] = b;
return dict;
}
private int indexOf(String str, String[] dict) {
for (int i = 0; i < dict.length; i++) {
if (str.equals(dict[i])) {
return i;
}
}
return -1;
}
private String[] getadj(String key, String[] dict) {
String[] rs = new String[dict.length];
char[] key_ary = key.toCharArray();
for (int i = 0; i < dict.length; i++) {
if (key.equals(dict[i])) {
continue;
}
char[] dict_ary = dict[i].toCharArray();
int k = 0;
for (int j = 0; j < key_ary.length; j++) {
if (key_ary[j] == dict_ary[j]) {
k++;
}
}
if (key_ary.length - 1 == k) {
rs[i] = dict[i];
}
}
return rs;
}
}
编译运行通过,但是在庞果后台运行题目测试用例出现编译错误是怎么回事?
最新进展,提交错误的原因是我把题目原有的import删掉了一部分。
由于此题只有一次挑战机会,所以不得已又注册了一个账号,重新提交了一次。结果是挑战成功