由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
JobHunting版 - WordLadderII 看到很多解法比较长。 抛砖引玉,求更简洁解法。
相关主题
这段word ladder II怎么改?word ladder能只用一个queue搞定吗?
leetcode 129word ladder 时间空间复杂度是多少, bfs 解的
请教word ladder| |一道电面题,分享下, 这个题应该用哪几个data structure?
Word ladder II 感觉算法已经是最优了,但是过不了大测试,能不能帮忙看看?大家帮我看看这个程序哪里有问题啊!!
leetcode 上 wordladderII 求教Word Ladder几个test case 没看明白
Time limit exceeded for Word Ladder(leetcode)问一个word ladder的题目
word ladder ii 谁给个大oj不超时的?LeetCode: Word Ladder
Leetcode word ladder 求助!一道面试题
相关话题的讨论汇总
话题: string话题: arraylist话题: ladder话题: new话题: hashset
进入JobHunting版参与讨论
1 (共1页)
A****L
发帖数: 138
1
public class WordLadderII {
public class Ladder { //Define Ladder class it's important
public Ladder parent;
public String word;
public Ladder(Ladder prev,String w) {parent=prev;word=w;}
}
public ArrayList> findLadders(String start, String end
, HashSet dict) {
ArrayList> ladders = new ArrayList String>>();
Ladder ladder = new Ladder(null,end); //Here we look from end to
start because we need to reverse the output
Queue q = new ArrayDeque();
q.add(ladder);
int count=1; //count the number of words for each level
while(!q.isEmpty()) {
HashSet set = new HashSet();
int cur=0;
for(int i=0;i Ladder curLadder = q.poll();
String str = curLadder.word;
for(int j=0;j any one of 26 letters
char[] wordChar = str.toCharArray();
for(char c='a';c<='z';c++) {
wordChar[j]=c;
String s = new String(wordChar);
Ladder newLadder = new Ladder(curLadder, s);
if(s.equals(start)) {//find and add to the list
ArrayList list = new ArrayList();
while(newLadder!=null) {
list.add(newLadder.word);
newLadder=newLadder.parent;
}
ladders.add(list);
}
else if(dict.contains(s) && !s.equals(str)) {//
filter those not in dict and itself
q.add(newLadder);
set.add(s);
cur++;// increase the number of nodes of the
next level
}
}
}
}
if(ladders.size()>0) return ladders; //if found then they are
the shortest distance return
dict.removeAll(set); // avoid revisiting any nodes of parent
levels
count=cur;
}
return ladders;
}
}
j**********m
发帖数: 51
2
写的很好啊!学习
c********l
发帖数: 8138
3
简洁不是最终极的目标,有时候需要reduce runtime complexity
见我之前写的
http://www.mitbbs.com/article/JobHunting/32658475_3.html
//MITBBS' article system will mess up the source code
// You may probably need to re-arrange the line breaks
// by coupondeal@mitbbs
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class Solution {

public static void main(String[] args) {
Solution sol = new Solution();
String[] dictStrArr = new String[] {
"dose","ends","dine","jars","prow","soap","guns","hops","
cray","hove","ella","hour","lens","jive","wiry","earl","mara","part","flue",
"putt","rory","bull","york","ruts","lily","vamp","bask","peer","boat","dens"
,"lyre","jets","wide","rile","boos","down","path","onyx","mows","toke","soto
","dork","nape","mans","loin","jots","male","sits","minn","sale","pets","
hugo","woke","suds","rugs","vole","warp","mite","pews","lips","pals","nigh",
"sulk","vice","clod","iowa","gibe","shad","carl","huns","coot","sera","mils"
,"rose","orly","ford","void","time","eloy","risk","veep","reps","dolt","hens
","tray","melt","rung","rich","saga","lust","yews","rode","many","cods","
rape","last","tile","nosy","take","nope","toni","bank","jock","jody","diss",
"nips","bake","lima","wore","kins","cult","hart","wuss","tale","sing","lake"
,"bogy","wigs","kari","magi","bass","pent","tost","fops","bags","duns","will
","tart","drug","gale","mold","disk","spay","hows","naps","puss","gina","
kara","zorn","boll","cams","boas","rave","sets","lego","hays","judy","chap",
"live","bahs","ohio","nibs","cuts","pups","data","kate","rump","hews","mary"
,"stow","fang","bolt","rues","mesh","mice","rise","rant","dune","jell","laws
","jove","bode","sung","nils","vila","mode","hued","cell","fies","swat","
wags","nate","wist","honk","goth","told","oise","wail","tels","sore","hunk",
"mate","luke","tore","bond","bast","vows","ripe","fond","benz","firs","zeds"
,"wary","baas","wins","pair","tags","cost","woes","buns","lend","bops","code
","eddy","siva","oops","toed","bale","hutu","jolt","rife","darn","tape","
bold","cope","cake","wisp","vats","wave","hems","bill","cord","pert","type",
"kroc","ucla","albs","yoko","silt","pock","drub","puny","fads","mull","pray"
,"mole","talc","east","slay","jamb","mill","dung","jack","lynx","nome","leos
","lade","sana","tike","cali","toge","pled","mile","mass","leon","sloe","
lube","kans","cory","burs","race","toss","mild","tops","maze","city","sadr",
"bays","poet","volt","laze","gold","zuni","shea","gags","fist","ping","pope"
,"cora","yaks","cosy","foci","plan","colo","hume","yowl","craw","pied","toga
","lobs","love","lode","duds","bled","juts","gabs","fink","rock","pant","
wipe","pele","suez","nina","ring","okra","warm","lyle","gape","bead","lead",
"jane","oink","ware","zibo","inns","mope","hang","made","fobs","gamy","fort"
,"peak","gill","dino","dina","tier"
};
HashSet dict = new HashSet ();
for (int i=0; i dict.add(dictStrArr[i]);
}
System.out.println("begin");
long t0 = System.currentTimeMillis();
sol.findLadders("nape", "mild", dict);
long t1 = System.currentTimeMillis();
System.out.println(t1-t0);
}

ArrayList> results;
Map> reversePath;
Set toVisit;
String start; String end;
public ArrayList> findLadders(String start, String end
, HashSet dict) {
results = new ArrayList>();
reversePath = new HashMap>();
toVisit = (HashSet) dict.clone();
toVisit.add(end);

this.start = start;
this.end = end;

bfs();
ArrayList path = new ArrayList();
populateOutput(end, path);
return results;

}
private void populateOutput(String tgt, ArrayList path) {
path.add(0, tgt);
if (tgt.equals(start)) {
results.add(path);
return;
}
ArrayList srcs = reversePath.get(tgt);
if (srcs != null) {
for (int i=0; i String srci = srcs.get(i);
ArrayList pathI = (ArrayList) path.clone();
populateOutput(srci, pathI);
}
}
}
private void bfs() {
boolean found = false;
char[] chrArr;
int wordLength = start.length(); // Cache to accelerate
ArrayList currLevel = new ArrayList();
currLevel.add(start);
while (!found) {
if (currLevel.isEmpty()) {
//No solution at all
break;
}
int currLevelSize = currLevel.size();
for (int i=0; i toVisit.remove(currLevel.get(i));
}
ArrayList nextLevel = new ArrayList();
for (int i=0; i String currStr = currLevel.get(i);

if (found) {
if (isDiffByOne(currStr, end, wordLength)) {
addSegment(currStr, end);
}
}
else {
outerFor:
for (int j=0; j chrArr = currStr.toCharArray(); // reset chrArr
for (char chr = 'a'; chr<='z'; chr++) {
chrArr[j] = chr;
String candidate = new String(chrArr);
if (toVisit.contains(candidate)) {
addSegment(currStr, candidate);

if (candidate.equals(end)) {
found = true;
break outerFor;
}
else {
nextLevel.add(candidate);
}
}
}
}
}
} // for currLevel loop
currLevel = nextLevel;
}

}

private void addSegment(String src, String tgt) {
ArrayList list = reversePath.get(tgt);
if (list == null) {
list = new ArrayList();
reversePath.put(tgt, list);
list.add(src);
}
else {
if (!list.contains(src)) {
list.add(src);
}
}
}
private boolean isDiffByOne(String src, String tgt, int wordLength) {
int diff = 0;
for (int i=0; i if (src.charAt(i)!=tgt.charAt(i)) {
if (diff>=1)
return false;
diff ++ ;
}
}
return (diff==1);
}
}
f******n
发帖数: 279
4
mark
c*******2
发帖数: 60
5
说说我自己的看法.
首先我同意三楼的, 代码长短不是最重要的, 还得看效率.
楼主的代码确实短, 想必花了心思压缩.
但我觉得有几个问题.
一个问题是每个Ladder object有只有一个prev指针.
这种情况下, 如果某个单词在很多个ladder里面出现的话, 必须要构造很多个Ladder
objects. 不知这样的空间效率如何.
第二个问题是第一个while循环的终止条件是queue是empty的, 如果我没理解错的话.
这样即使是找到了start, 循环还会继续下去. 因为楼主在dict里把出现过的单词都
remove了, 循环必定会终止而且也不会出现更长的ladder. 算法是正确的, 但终止时间
可能会晚了点. 应该在找到start后就可以终止下一个level的循环了.
第三个问题是修改了dict...这个不重要, 可以像三楼那样clone一个就行. 我个人是用
了个hashmap保存已经visit过的word, 因为我的这个hashmap还有其他用处,所以也就顺
便用在这里, 没有clone.
ps三楼: 我看你在你的帖子里说你的代码跑大数据是485ms. 我用我的代码跑了下是70-
110ms.
我的代码在
https://github.com/chen1502/LeetCode/blob/master/wordLadderII.java
A****L
发帖数: 138
6
谢谢你的意见。 我也肯定是同意效率要高才行的。我的意思是在保证效率的前提下,
越简单越好。 具体到这题,基本前提就是能pass OJ。另外要是代码让人容易理解就更
好了。 我的code 的思路就是 一层一层 推进, 如果在到达某层找到了 path 那么到
这层 所有可行的path 都是最短的,然后就直接返回结果了。具体就是下面这个语句。
if(ladders.size()>0) return ladders;
//if found then they are the shortest distance return
虽然 while 终止条件是 empty 但是某一层找到了就返回结果了。
每个ladder 只记录它是从哪个ladder 下来的。 如果一个ladder 下来有很多
children ladder, 那么这个ladder 可能出现在很多path 里,但是这里不会重新产生
ladder object, 只有一个ladder object。 因为所有的children 都指向了它(同一
个object)。
空间存储上,如果clone 记录visited 那么一直是会存在两个dict了。
这里直接在原来的dict 上操作,不需要额外一个size 的dict。 而且随着层数的增加
,size 在变小。 当然如果题目要求不能改变原来的dict。 那就备份一个。这样跟用
hashmap 记录 visited 效率应该一样了就。
谢谢。

【在 c*******2 的大作中提到】
: 说说我自己的看法.
: 首先我同意三楼的, 代码长短不是最重要的, 还得看效率.
: 楼主的代码确实短, 想必花了心思压缩.
: 但我觉得有几个问题.
: 一个问题是每个Ladder object有只有一个prev指针.
: 这种情况下, 如果某个单词在很多个ladder里面出现的话, 必须要构造很多个Ladder
: objects. 不知这样的空间效率如何.
: 第二个问题是第一个while循环的终止条件是queue是empty的, 如果我没理解错的话.
: 这样即使是找到了start, 循环还会继续下去. 因为楼主在dict里把出现过的单词都
: remove了, 循环必定会终止而且也不会出现更长的ladder. 算法是正确的, 但终止时间

c********l
发帖数: 8138
7
485ms是之前疏忽了用arraylist的时间
换成hashset之后就是<100ms
我自己的机器上也是100ms 左右,只不过这个结果好像没放在原贴里面

70-

【在 c*******2 的大作中提到】
: 说说我自己的看法.
: 首先我同意三楼的, 代码长短不是最重要的, 还得看效率.
: 楼主的代码确实短, 想必花了心思压缩.
: 但我觉得有几个问题.
: 一个问题是每个Ladder object有只有一个prev指针.
: 这种情况下, 如果某个单词在很多个ladder里面出现的话, 必须要构造很多个Ladder
: objects. 不知这样的空间效率如何.
: 第二个问题是第一个while循环的终止条件是queue是empty的, 如果我没理解错的话.
: 这样即使是找到了start, 循环还会继续下去. 因为楼主在dict里把出现过的单词都
: remove了, 循环必定会终止而且也不会出现更长的ladder. 算法是正确的, 但终止时间

c********l
发帖数: 8138
8
你放在github上的代码跑得快,还是我的代码跑得快?相差多少?
(不是为了比赛,呵呵,为了提高)

https://github.com/chen1502/LeetCode/blob/master/wordLadderII.java

【在 c*******2 的大作中提到】
: 说说我自己的看法.
: 首先我同意三楼的, 代码长短不是最重要的, 还得看效率.
: 楼主的代码确实短, 想必花了心思压缩.
: 但我觉得有几个问题.
: 一个问题是每个Ladder object有只有一个prev指针.
: 这种情况下, 如果某个单词在很多个ladder里面出现的话, 必须要构造很多个Ladder
: objects. 不知这样的空间效率如何.
: 第二个问题是第一个while循环的终止条件是queue是empty的, 如果我没理解错的话.
: 这样即使是找到了start, 循环还会继续下去. 因为楼主在dict里把出现过的单词都
: remove了, 循环必定会终止而且也不会出现更长的ladder. 算法是正确的, 但终止时间

c*******2
发帖数: 60
9
我在我电脑上测试了下.
用你那个帖子里的大数据的话, 我的是100ms左右(测试多次), 你和楼主的都是200左右.
然后我自己弄了个test case, dict里包含了所有长度为4的String, 也就是有26^4个
words. 然后随便弄了两个没有重复字母的单词, 比如abcd, efgh. 这回我和你的时间
差不多2000ms, 楼主的到了13000ms

【在 c********l 的大作中提到】
: 你放在github上的代码跑得快,还是我的代码跑得快?相差多少?
: (不是为了比赛,呵呵,为了提高)
:
: https://github.com/chen1502/LeetCode/blob/master/wordLadderII.java

c********l
发帖数: 8138
10
不对啊,
你前面说用我贴子里面的大数据,我的code是100ms出头一些,怎么又变成200ms了?
另外,假定的确像你说的,中等数据有2倍的差距。
那么相对于我的code,你的code优化在哪儿?

右.

【在 c*******2 的大作中提到】
: 我在我电脑上测试了下.
: 用你那个帖子里的大数据的话, 我的是100ms左右(测试多次), 你和楼主的都是200左右.
: 然后我自己弄了个test case, dict里包含了所有长度为4的String, 也就是有26^4个
: words. 然后随便弄了两个没有重复字母的单词, 比如abcd, efgh. 这回我和你的时间
: 差不多2000ms, 楼主的到了13000ms

相关主题
Time limit exceeded for Word Ladder(leetcode)word ladder能只用一个queue搞定吗?
word ladder ii 谁给个大oj不超时的?word ladder 时间空间复杂度是多少, bfs 解的
Leetcode word ladder 求助!一道电面题,分享下, 这个题应该用哪几个data structure?
进入JobHunting版参与讨论
c*******2
发帖数: 60
11
哦, 对, 是在找到结果就终止了.
空间上我还是觉得重复了.
比如 start = "abcd", end = "efgh".
dict 是所有长度为4的string.
那么中间的每个字母的indegree和outdegree都大于1.
比如: "abcd" -> "ebcd" -> "efcd" -> "efgd" -> "efgh"
"abcd" -> "afcd" -> "efcd" -> "efch" -> "efgh"
由于你只有一个pointer, "efcd"这个Ladder object至少要创建两次, 不管这个
pointer是指向前还是后.



【在 A****L 的大作中提到】
: 谢谢你的意见。 我也肯定是同意效率要高才行的。我的意思是在保证效率的前提下,
: 越简单越好。 具体到这题,基本前提就是能pass OJ。另外要是代码让人容易理解就更
: 好了。 我的code 的思路就是 一层一层 推进, 如果在到达某层找到了 path 那么到
: 这层 所有可行的path 都是最短的,然后就直接返回结果了。具体就是下面这个语句。
: if(ladders.size()>0) return ladders;
: //if found then they are the shortest distance return
: 虽然 while 终止条件是 empty 但是某一层找到了就返回结果了。
: 每个ladder 只记录它是从哪个ladder 下来的。 如果一个ladder 下来有很多
: children ladder, 那么这个ladder 可能出现在很多path 里,但是这里不会重新产生
: ladder object, 只有一个ladder object。 因为所有的children 都指向了它(同一

A****L
发帖数: 138
12
对的,你这个问题很好。的确是如果两个word 是不同的路径上的话 是会单独一个
ladder object。不然会交叉了。 我再看看能不能改进。 谢谢。 另外你们说的test
时间问题。 不知道你们在 leetcode 上run所有cases 的时间是多少。 我的run time
显示的是1456 ms

【在 c*******2 的大作中提到】
: 哦, 对, 是在找到结果就终止了.
: 空间上我还是觉得重复了.
: 比如 start = "abcd", end = "efgh".
: dict 是所有长度为4的string.
: 那么中间的每个字母的indegree和outdegree都大于1.
: 比如: "abcd" -> "ebcd" -> "efcd" -> "efgd" -> "efgh"
: "abcd" -> "afcd" -> "efcd" -> "efch" -> "efgh"
: 由于你只有一个pointer, "efcd"这个Ladder object至少要创建两次, 不管这个
: pointer是指向前还是后.
:

A****L
发帖数: 138
13
run了下你的code 的确要比我的快不少。我学习下,看看能不能结合下。 皆能简洁又
能和你的一样快。

【在 c*******2 的大作中提到】
: 哦, 对, 是在找到结果就终止了.
: 空间上我还是觉得重复了.
: 比如 start = "abcd", end = "efgh".
: dict 是所有长度为4的string.
: 那么中间的每个字母的indegree和outdegree都大于1.
: 比如: "abcd" -> "ebcd" -> "efcd" -> "efgd" -> "efgh"
: "abcd" -> "afcd" -> "efcd" -> "efch" -> "efgh"
: 由于你只有一个pointer, "efcd"这个Ladder object至少要创建两次, 不管这个
: pointer是指向前还是后.
:

l*******b
发帖数: 2586
14
这个心中永远的痛呀。。。最早二爷的那个程序短而且快。学习写了两三个版本,纸上
过了两遍,被面到的时候居然没写好。。。
这里写了个javascript版的,小伙伴们别像那个state machine版的valid number一样
揪出来批斗了呀。。。
http://nodejs-luckynoob.rhcloud.com/apps/jsapps.html
c********l
发帖数: 8138
15
statemachine版?

【在 l*******b 的大作中提到】
: 这个心中永远的痛呀。。。最早二爷的那个程序短而且快。学习写了两三个版本,纸上
: 过了两遍,被面到的时候居然没写好。。。
: 这里写了个javascript版的,小伙伴们别像那个state machine版的valid number一样
: 揪出来批斗了呀。。。
: http://nodejs-luckynoob.rhcloud.com/apps/jsapps.html

a*****n
发帖数: 158
16
Mark
l*******b
发帖数: 2586
17
http://www.mitbbs.com/article_t/JobHunting/32675497.html
就是这个呀,过一阵子就被拿来批斗一番。。。

【在 c********l 的大作中提到】
: statemachine版?
A****L
发帖数: 138
18
优化后的代码。 速度和你的差不多了。
https://github.com/notbrucelee/Leetcode/blob/master/WordLadderII.java

【在 c*******2 的大作中提到】
: 哦, 对, 是在找到结果就终止了.
: 空间上我还是觉得重复了.
: 比如 start = "abcd", end = "efgh".
: dict 是所有长度为4的string.
: 那么中间的每个字母的indegree和outdegree都大于1.
: 比如: "abcd" -> "ebcd" -> "efcd" -> "efgd" -> "efgh"
: "abcd" -> "afcd" -> "efcd" -> "efch" -> "efgh"
: 由于你只有一个pointer, "efcd"这个Ladder object至少要创建两次, 不管这个
: pointer是指向前还是后.
:

f****8
发帖数: 33
19
Thanks sharing!
The key point for this problem is that how to discover the neighbor nodes:
Find the neighbor nodes by constructing and searching them in the dict (for
each found node in last round, need 25 x strlen times string comparing),
rather than enumerating all the remain nodes in the dict (for each found
node in last round, need dict.size() comparing).
m*********y
发帖数: 111
20
ding!
1 (共1页)
进入JobHunting版参与讨论
相关主题
一道面试题leetcode 上 wordladderII 求教
多线程算sparse matrix connected components怎么做?Time limit exceeded for Word Ladder(leetcode)
leetcode出了新题word ladderword ladder ii 谁给个大oj不超时的?
leetcode word break II DFS 超时Leetcode word ladder 求助!
这段word ladder II怎么改?word ladder能只用一个queue搞定吗?
leetcode 129word ladder 时间空间复杂度是多少, bfs 解的
请教word ladder| |一道电面题,分享下, 这个题应该用哪几个data structure?
Word ladder II 感觉算法已经是最优了,但是过不了大测试,能不能帮忙看看?大家帮我看看这个程序哪里有问题啊!!
相关话题的讨论汇总
话题: string话题: arraylist话题: ladder话题: new话题: hashset