庞果网 最小操作数

5 篇文章 0 订阅
4 篇文章 0 订阅
来源庞果英雄会的挑战题
此题是个图论问题,把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删掉了一部分。
由于此题只有一次挑战机会,所以不得已又注册了一个账号,重新提交了一次。结果是挑战成功
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值