9.1 Word Ladder

Link: https://oj.leetcode.com/problems/word-ladder/

My thought: 1 How to build find a transformation? 2 How to make sure that this transformation is shortest? 

Approach: 

BFS. Each String is viewed as a node. If two Strings only have a letter difference, then there is an edge between them. The shortest transformation then becomes finding the shortest path in this graph.

word-ladder

(Figure: http://www.programcreek.com/2012/12/leetcode-word-ladder/)

Time: If we assume that String has length L. Then Time = O(min(26^L, size(dict)). When words in dict can have different length other than L.

public class Solution {
    public int ladderLength(String start, String end, Set<String> dict) {
        if(start == null || end == null || start.length()==0 ||end.length() ==0 || start.length()!= end.length()){
            return 0;
        }
        LinkedList<String> queue = new LinkedList<String>();
        HashSet<String> visited = new HashSet<String>();
        queue.add(start);
        visited.add(start);
        int level = 1;
        int lastNum = 1;//num of nodes in last level
        int curNum = 0;//num of nodes in current level
        while(!queue.isEmpty()){
            String cur = queue.poll();
            lastNum--;
            //change one letter in cur
            for(int i = 0; i < cur.length(); i++){
                char[] charCur = cur.toCharArray();
                for(char c = 'a'; c <='z'; c++){//for each adjacent String of cur (those only need to change one letter)
                    charCur[i] = c;
                    String nCur = new String(charCur);
                    if(nCur.equals(end)){//only one step from start to end
                        return level+1;
                    }
                    if(dict.contains(nCur) && !visited.contains(nCur)){
                        curNum++;
                        visited.add(nCur);
                        queue.add(nCur);
                    }
                }
            }
            if(lastNum == 0){
                lastNum = curNum;
                curNum = 0;
                level++;
            }
            
        }
        return 0;
    }
}

Note: 

1 We cannot put  this before the for loop. Its because when charCur is modified, cur will be modified accordingly.char[] charCur = cur.toCharArray(); 

2 To optimize it, We can add "dict.remove(nCur);" in if(dict.contains(nCur) && !visited.contains(nCur)){

http://blog.csdn.net/zxzxy1988/article/details/8591890

But we cannot do this optimization in Word Ladder II.

"(1)在本层能遍历到该元素。也就是说,我们到达这个元素有两条路径,而且它们都是最短路径。
比如hot->hog->dog->dig和hot->dot->dog->dig,那么在第一次遍历距离hot为1的元素时,我们找到了hog和dot。对hog遍历时,我们找到了dog,并且将其从字典中删除。那么在遍历距离dot为1的元素时,我们实际上是找不到dog的,因为已经被删除了。对于本题来说,是没有什么影响的,因为到dog距离都是3,到dig距离都是4。
(2)在更下层我们才能够遍历到该元素。比如hot->dot->dog->dig和hot->hat->dat->dag->dog->dig,如果第一次我们找到了dog并且将其删除,那么第二次我们实际上是找不到这个元素的。这样对于本题来说,没有任何影响。"


第二遍:@8.25.2014

我写的:框架基本正确。但是要记得BFS需要设两个变量记录当前层和下一层的节点数

public class Solution {
    public int ladderLength(String start, String end, Set<String> dict) {
        //BFS, each level stores all strings with one-char difference with the string on the above level
        Queue<String> queue = new Queue<String>();
        queue.add(start);
        int level = 0;
        while(!queue.isEmpty()){
            String str = queue.poll();
            char[] strArr = str.toCharArray();
            for(int i = 0; i < strArr.length; i++){
                for(char c = 'a'; c <='z'; c++){
                    if(c == strArr[i]) continue;
                    else{
                        strArr[i] = c;
                        String trans = new String(strArr);
                        if(dict.contains(trans)){
                            
                            if(trans.equals(end)){
                                return level;
                            }
                            queue.add(trans);
                            
                        }
                    }
                }
            }
            level++;
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值