LeetCode126 Word Ladder II


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


Java Solution: github

package leetcode;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;

/*
 * 	Given two words (beginWord and endWord), and a dictionary's word list, 
 * 	find all shortest transformation sequence(s) 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"]
	Return
	  [
	    ["hit","hot","dot","dog","cog"],
	    ["hit","hot","lot","log","cog"]
	  ]
	Note:
	All words have the same length.
	All words contain only lowercase alphabetic characters.
 */

import java.util.LinkedList;
import java.util.List;
import java.util.Queue;


/**
 * @author      zxwtry
 * @email       zxwtry@qq.com
 * @project     OJ
 * @package     leetcode
 * @file        P126_WordLadderII.java
 * @type        P126_WordLadderII
 * @date        2016年12月13日 下午5:16:11
 * @details     Solution: AC 204ms 65.85%
 */
public class P126_WordLadderII {
    public static void main(String[] args) {
        String s = "hit";
        String e = "cog";
        String[] ss = {"hot","dot","dog","lot","log","cog"};
        List<String> w = Arrays.asList(ss);
        System.out.println(new Solution().findLadders(s, e, w));
                
    }
	static class Solution {
	    public List<List<String>> findLadders(String s, String t, List<String> w) {
	        List<List<String>> ans = new LinkedList<List<String>>();
	        if (s == null || t == null || w == null) {
	            if (s == null && t == null)
	                ans.add(Arrays.asList((String)null));
	            return ans;
	        }
	        if (s.equals(t)) {
	            ans.add(Arrays.asList(s));
	            return ans;
	        }
	        int sn = s.length();
	        if (w.size() == 0) return ans;
	        HashSet<String> nv = new HashSet<String>(w);
	        HashSet<String> hv = new HashSet<String>();
	        if (! nv.contains(t)) return ans;
	        nv.add(s);
	        Queue<String> q = new LinkedList<String>();
	        q.add(s);
	        HashMap<String, List<String>> m = new HashMap<String, List<String>>();
	        char[] cs = new char[sn];
	        boolean isFind = false;
	        while (! q.isEmpty()) {
	            int size = q.size();
	            while (size -- > 0) {
	                String n = q.poll();
	                for (int i = 0; i < sn; i ++) cs[i] = n.charAt(i);
	                for (int i = 0; i < sn; i ++) {
	                    for (char c = 'a'; c <= 'z'; c ++) {
	                        cs[i] = c;
	                        String nn = new String(cs);
	                        if (! nv.contains(nn)) continue;
	                        if (hv.add(nn)) q.add(nn);
	                        if (! m.containsKey(nn)) m.put(nn, new LinkedList<String>());
	                        m.get(nn).add(n);
	                        if (nn.equals(t)) isFind = true; 
	                    }
	                    cs[i] = n.charAt(i);
	                }
	            }
	            if (isFind) break;
	            nv.removeAll(hv);
	            hv.clear();
	        }
	        System.out.println(m);
	        find(t, s, new LinkedList<String>(), m, ans);
	        return ans;
	    }
        private void find(String t, String s, LinkedList<String> l, HashMap<String, List<String>> m,
                List<List<String>> ans) {
            l.addFirst(t);
            if (t.equals(s)) {
                ans.add(new LinkedList<String>(l));
            } else {
                for (String v : m.getOrDefault(t, new ArrayList<String>(0)))
                    find(v, s, l, m, ans);
            }
            l.removeFirst();
        }
	}
	
}


CPP Solution: github

#pragma warning(disable:4786)
#pragma warning(disable:4503)
/*
    url: leetcode.com/problems/word-ladder-ii
    too many advanced data structure
    use cpp
    Solution: AC 259ms 51.41%
*/

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

using namespace std;

class Solution {
public:
    void find(string t, string s, vector<string >& v, map<string, vector<string > >& m, vector<vector<string > >& ans) {
        v.insert(v.begin(), t);
        if (! t.compare(s)) {
            ans.push_back(v);
        } else if (m.count(t)) {
            for (vector<string >::iterator iter = m[t].begin(); iter != m[t].end(); iter ++)
                find(*iter, s, v, m, ans);
        }
        v.erase(v.begin());
    }

    vector<vector<string > > findLadders(string s, string t, vector<string>& w) {
        vector<vector<string > > ans;
        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;
        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;
            for (set<string >::iterator iter = hv.begin(); iter != hv.end(); iter ++)
                nv.erase(*iter);
            hv.clear();
        }
        vector<string > v;
        find(t, s, v, m, ans);
        return ans;
    }
};

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]);
    vector<vector<string > > ans = Solution().findLadders(s, t, w);
    for (i = 0; i < ans.size(); i ++) {
        cout<<"+++++++++"<<endl;    
        for (int j = 0; j < ans[i].size(); j ++) {
            cout<<ans[i][j]<<" ";
        }
        cout<<endl;
    }
    return 0;
}


Python Solution: github

#coding=utf-8

'''
    url: leetcode.com/problems/word-ladder-ii
    @author:     zxwtry
    @email:      zxwtry@qq.com
    @date:       2017年5月5日
    @details:    Solution:  86ms 36.12%
'''
from jinja2._compat import unichr
from re import search

class Solution(object):
    def backtrace(self, m, b, e, rec, ans):
        rec.insert(0, e)
        if b == e:
            ans.append(list(rec))
        else:
            for v in m[e]:
                self.backtrace(m, b, v, rec, ans)
        rec.remove(rec[0])
        
    def findLadders(self, b, e, w):
        """
        :type b: str
        :type e: str
        :type w: List[str]
        :rtype: List[List[str]]
        """
        n = 0 if b == None else len(b)
        if n == 0: return [[""]]
        nv, hv = set(w), set()
        m = {w[i]:set() for i in range(len(w))}
        m[b] = set()
        nv.add(b)
        q, isFind = [b], False
        while len(q) != 0:
            size = len(q)
            while size > 0: 
                size = size-1
                v = q.pop()
                cs = [v[i] for i in range(n)]
                for i in range(n):
                    for k in range(26):
                        cs[i] = unichr(97+k)
                        cc = "".join(cs)
                        if not (cc in nv): continue
                        if cc == e: isFind = True
                        if (cc not in hv):
                            q.append(cc)
                            hv.add(cc)
                        m[cc].add(v)
                    cs[i] = v[i]
            if isFind: break
            for vv in hv: nv.remove(vv)
            hv.clear()
        ans, rec = [], []
        print(m)
        self.backtrace(m, b, e, rec, ans)
        return ans
        
        
if __name__ == "__main__":
    b = 'hit'
    e = 'cog'
    w = ["hot","dot","dog","lot","log","cog"]
    print(Solution().findLadders(b, e, w))
    





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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值