LeetCode127 Word Ladder



详细见:leetcode.com/problems/word-ladder


Java Solution: github

package leetcode;

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

/*
 * 	Given two words (beginWord and endWord), and a dictionary's word list,
 *  find the length of shortest transformation sequence
 *   from beginWord to endWord, such that:

	Only one letter can be changed at a time
	Each intermediate word must exist in the word list
	For example,
	
	Given:
	beginWord = "hit"
	endWord = "cog"
	wordList = ["hot","dot","dog","lot","log"]
	As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
	return its length 5.
	
	Note:
	Return 0 if there is no such transformation sequence.
	All words have the same length.
	All words contain only lowercase alphabetic characters.
 */

import java.util.Set;

public class P127_WordLadder {
	/*
	 * 	184 ms
	 * 	6.20%
	 */
	static class Solution_Answer {
		long count = 0;
		long count_replace = 0;
	    public int ladderLength(String start, String end, Set<String> dict) {
	        if (dict == null) {
	            return 0;
	        }
	        if (start.equals(end)) {
	            return 1;
	        }
	        dict.add(start);
	        dict.add(end);
	        HashSet<String> hash = new HashSet<String>();
	        Queue<String> queue = new LinkedList<String>();
	        queue.offer(start);
	        hash.add(start);
	        int length = 1;
	        while(!queue.isEmpty()) {
	            length++;
	            int size = queue.size();
	            for (int i = 0; i < size; i++) {
	                String word = queue.poll();
	                for (String nextWord: getNextWords(word, dict)) {
	                    if (hash.contains(nextWord)) {
	                        continue;
	                    }
	                    if (nextWord.equals(end)) {
	                    	System.out.println("count : " + count);
	                    	System.out.println("count_replace : " + count_replace);
	                        return length;
	                    }
	                    count ++;
	                    hash.add(nextWord);
	                    queue.offer(nextWord);
	                }
	            }
	        }
	        return 0;
	    }

	    // replace character of a string at given index to a given character
	    // return a new string
	    private String replace(String s, int index, char c) {
	        char[] chars = s.toCharArray();
	        chars[index] = c;
	        count_replace ++;
	        return new String(chars);
	    }
	    
	    // get connections with given word.
	    // for example, given word = 'hot', dict = {'hot', 'hit', 'hog'}
	    // it will return ['hit', 'hog']
	    private ArrayList<String> getNextWords(String word, Set<String> dict) {
	        ArrayList<String> nextWords = new ArrayList<String>();
	        for (char c = 'a'; c <= 'z'; c++) {
	            for (int i = 0; i < word.length(); i++) {
	                if (c == word.charAt(i)) {
	                    continue;
	                }
	                String nextWord = replace(word, i, c);
	                if (dict.contains(nextWord)) {
	                    nextWords.add(nextWord);
	                }
	            }
	        }
	        return nextWords;
	    }
	}
}


C Solution: github

#pragma warning(disable:4786)
#pragma warning(disable:4503)

/*
    url: leetcode.com/problems/word-ladder
    need to use advanced data structure
    choose cpp
    AC 323ms 29.09%
*/

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <queue>
#include <set>

using namespace std;

int ladderLength(string s, string t, vector<string >& w) {
    int sn = s.size() , i;
    set<string > nv , hv;
    for (i = 0; i < w.size(); i ++) nv.insert(w[i]);
    map<string, vector<string > > m;
    queue<string > q;
    nv.insert(s);
    q.push(s);
    bool isFind = false;
    int ans = 2;
    while (! q.empty()) {
        int size = q.size();
        while (size -- > 0) {
            string n = q.front();
            string v = n;
            q.pop();
            for (i = 0; i < sn; i ++) {
                for (char c = 'a'; c <= 'z'; c ++) {
                    v[i] = c;
                    if (! nv.count(v)) continue;
                    if (! hv.count(v)) {
                        hv.insert(v);
                        q.push(v);
                    }
                    m[v].push_back(n);
                    if (! v.compare(t)) isFind = true;
                }
                v[i] = n[i];
            }
        }
        if (isFind) break;
        ans ++;
        for (set<string >::iterator iter = hv.begin(); iter != hv.end(); iter ++)
            nv.erase(*iter);
        hv.clear();
    }
    return isFind ? ans : 0;;
}

int main() {

    string g[] = {"hot","dot","dog","lot","log","cog"};
    string s = "hit", t = "cog";
    vector<string > w;
    int i;
    for (i = 0; i < (sizeof(g)/sizeof(g[0])); i ++) w.push_back(g[i]);
    int ans = ladderLength(s, t, w);
    cout<<ans<<endl;
    return 0;

}


Python Solution: github


#coding=utf-8

'''
    url: leetcode.com/problems/word-ladder
    @author:     zxwtry
    @email:      zxwtry@qq.com
    @date:       2017年5月12日
    @details:    Solution:  902ms 44.52%
'''

from jinja2._compat import unichr

class Solution(object):
    def ladderLength(self, b, e, w):
        """
        :type b: str
        :type e: str
        :type w: List[str]
        :rtype: int
        """
        nv = set(w)
        hv = set()
        sn = len(b)
        q = []
        nv.add(b)
        q.append(b)
        isFind = False
        count = 2
        while True:
            l = len(q)
            if l == 0: break
            while l > 0:
                l -= 1
                s = q[0]
                q.remove(q[0])
                cs = [s[i] for i in range(sn)]
                for i in range(sn):
                    for j in range(26):
                        cs[i] = unichr(97+j)
                        ns = "".join(cs)
                        if not ns in nv: continue
                        if not ns in hv:
                            hv.add(ns)
                            q.append(ns)
                        if ns == e: isFind = True
                    cs[i] = s[i]
            if isFind: break
            count += 1
            for v in hv: nv.remove(v)
            hv.clear()
        return 0 if not isFind else count
        

if __name__ == "__main__":
    b, e = "hit", "cog"
    w = ["hot","dot","hog","dog","lot","log","cog"]
#     b, e = "a", "c"
#     w = ["a", "b", "c"]
    print(Solution().ladderLength(b, e, w))




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值