Word Ladder II

Word Ladder II

问题:

Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:

  1. Only one letter can be changed at a time
  2. Each intermediate word must exist in the dictionary

思路:

  bfs dfs结合

我的代码:

public class Solution {
    public List<List<String>> findLadders(String start, String end, Set<String> dict) {
        if(isValid(start, end))
        {
            List<String> tmpList = new ArrayList<String>();
            tmpList.add(start);
            tmpList.add(end);
            list.add(tmpList);
            return list;
        }
        Set<String> rst = new HashSet<String>();
        for(String str : dict)
        {
            if(isValid(end,str))
            {
                rst.add(str);
            }
        }
        List<String> tmpList = new ArrayList<String>();
        dfs(tmpList, rst, dict, start, end);
        List<List<String>> result = new ArrayList<List<String>>();
        for(List<String> partList: list)
        {
            if(partList.size() == shortPath)
                result.add(partList);
        }
        return result;
    }
    private List<List<String>> list = new ArrayList<List<String>>();
    private int shortPath = Integer.MAX_VALUE;
    public void dfs(List<String> tmpList, Set<String> rst, Set<String> dict, String start, String end)
    {
        tmpList.add(start);
        if(rst.contains(start))  
        {
            tmpList.add(end);
            if(shortPath >= tmpList.size())
            {
                list.add(new ArrayList(tmpList));
                shortPath = tmpList.size();
            }
            tmpList.remove(tmpList.size()-1);
            tmpList.remove(tmpList.size()-1);
            return ;
        }
        for(char c = 'a'; c <= 'z'; c++)
        {
            for(int j = 0; j < start.length(); j++)
            {
                if(start.charAt(j) == c)  continue;
                String str = replace(start, j, c);
                if(dict.contains(str))
                {
                    dict.remove(str);
                    dfs(tmpList, rst, dict, str, end);
                    dict.add(str);
                }
            }
        }
        tmpList.remove(tmpList.size()-1);
    }
    private String replace(String s, int index, char c)
    {
        char[] chars = s.toCharArray();
        chars[index] = c;
        return new String(chars);
    }
    public boolean isValid(String one, String two)
    {
        int count = 0;
        for(int i = 0; i < one.length(); i++)
        {
            if(one.charAt(i) != two.charAt(i))
                count++;
        }
        return count == 1 ? true : false;
    }
}
View Code

他人代码:

public class Solution {
    public List<List<String>> findLadders(String start, String end,
            Set<String> dict) {
        List<List<String>> ladders = new ArrayList<List<String>>();
        Map<String, List<String>> map = new HashMap<String, List<String>>();
        Map<String, Integer> distance = new HashMap<String, Integer>();

        dict.add(start);
        dict.add(end);
 
        bfs(map, distance, start, end, dict);
        
        List<String> path = new ArrayList<String>();
        
        dfs(ladders, path, end, start, distance, map);

        return ladders;
    }

    void dfs(List<List<String>> ladders, List<String> path, String crt,
            String start, Map<String, Integer> distance,
            Map<String, List<String>> map) {
        path.add(crt);
        if (crt.equals(start)) {
            Collections.reverse(path);
            ladders.add(new ArrayList<String>(path));
            Collections.reverse(path);
        } else {
            for (String next : map.get(crt)) {
                if (distance.containsKey(next) && distance.get(crt) == distance.get(next) + 1) { 
                    dfs(ladders, path, next, start, distance, map);
                }
            }           
        }
        path.remove(path.size() - 1);
    }

    void bfs(Map<String, List<String>> map, Map<String, Integer> distance,
            String start, String end, Set<String> dict) {
        Queue<String> q = new LinkedList<String>();
        q.offer(start);
        distance.put(start, 0);
        for (String s : dict) {
            map.put(s, new ArrayList<String>());
        }
        
        while (!q.isEmpty()) {
            String crt = q.poll();

            List<String> nextList = expand(crt, dict);
            for (String next : nextList) {
                map.get(next).add(crt);
                if (!distance.containsKey(next)) {
                    distance.put(next, distance.get(crt) + 1);
                    q.offer(next);
                }
            }
        }
    }

    List<String> expand(String crt, Set<String> dict) {
        List<String> expansion = new ArrayList<String>();

        for (int i = 0; i < crt.length(); i++) {
            for (char ch = 'a'; ch <= 'z'; ch++) {
                if (ch != crt.charAt(i)) {
                    String expanded = crt.substring(0, i) + ch
                            + crt.substring(i + 1);
                    if (dict.contains(expanded)) {
                        expansion.add(expanded);
                    }
                }
            }
        }

        return expansion;
    }
}
View Code

学习之处:

  • 我的代码只能过小的数据集,大的数据集就超时了,主要是太多的的重复计算非最短路径中,需要先进行BFS确定哪些是最短的路径
  • 直接复制的别人的代码AC的,有点浮躁啊,看看了,下次再刷leetcode的时候,再自己写一遍,到了hard的难度了,越来越多的题,hold不住了。
  • 改掉自己身上不好的习惯,Day by day, 进步一点点

posted on 2015-05-19 17:27  zhouzhou0615  阅读(165)  评论(0编辑  收藏  举报

导航