My code:
public class WordDistance {
HashMap<String, Integer> dic;
public WordDistance(String[] words) {
dic = new HashMap<String, Integer>();
for (int i = 0; i < words.length; i++) {
for (int j = i + 1; j < words.length; j++) {
if (words[i].equals(words[j])) {
continue;
}
String key = genKey(words[i], words[j]);
if (!dic.containsKey(key)) {
dic.put(key, Math.abs(i - j));
}
else {
int dis = dic.get(key);
dic.put(key, Math.min(dis, Math.abs(i - j)));
}
}
}
}
public int shortest(String word1, String word2) {
String key = genKey(word1, word2);
return dic.containsKey(key) ? dic.get(key) : 0;
}
private String genKey(String s1, String s2) {
if (s1.compareTo(s2) > 0) {
return s2 + "_" + s1;
}
else {
return s1 + "_" + s2;
}
}
}
// Your WordDistance object will be instantiated and called as such:
// WordDistance wordDistance = new WordDistance(words);
// wordDistance.shortest("word1", "word2");
// wordDistance.shortest("anotherWord1", "anotherWord2");
这是我自己的做法。结果 TLE..
我在construct 的时候,复杂度是 O(MM avearge of word length)
但是我的shortest 很快。如果不考虑字符串操作带来的消耗,可以达到 O(1)
但是字符串操作有很多额外开销。
比如, compareTo
比如string concatenation
都是 O(n)的复杂度。
而且constructor 的复杂度太高。于是TLE
于是看了答案。自己写了下:
My code:
public class WordDistance {
HashMap<String, List<Integer>> dic = new HashMap<String, List<Integer>>();
public WordDistance(String[] words) {
for (int i = 0; i < words.length; i++) {
if (dic.containsKey(words[i])) {
dic.get(words[i]).add(i);
}
else {
List<Integer> list = new ArrayList<Integer>();
list.add(i);
dic.put(words[i], list);
}
}
}
public int shortest(String word1, String word2) {
List<Integer> l1 = dic.get(word1);
List<Integer> l2 = dic.get(word2);
int i1 = 0;
int i2 = 0;
int ret = Integer.MAX_VALUE;
while (i1 < l1.size() || i2 < l2.size()) {
if (i1 >= l1.size()) {
ret = Math.min(ret, Math.abs(l2.get(i2) - l1.get(l1.size() - 1)));
i2++;
}
else if (i2 >= l2.size()) {
ret = Math.min(ret, Math.abs(l1.get(i1) - l2.get(l2.size() - 1)));
i1++;
}
else {
ret = Math.min(ret, Math.abs(l1.get(i1) - l2.get(i2)));
if (l1.get(i1) < l2.get(i2)) {
i1++;
}
else {
i2++;
}
}
}
return ret;
}
}
// Your WordDistance object will be instantiated and called as such:
// WordDistance wordDistance = new WordDistance(words);
// wordDistance.shortest("word1", "word2");
// wordDistance.shortest("anotherWord1", "anotherWord2");
reference:
https://discuss.leetcode.com/topic/20643/java-solution-using-hashmap
他的constructor 复杂度是 O(M)
shortest 复杂度是 O(M + N)
总之,将constructor 的复杂度分担了一些给shortest()
然后就过了测试。
所以有这么一个问题。
如果两种解法。
解法一,
一个函数复杂度是 O(n ^ 2)
一个是 O(1)
解法二,
一个函数复杂度是 O(n)
一个是 O(n)
你更喜欢哪个?
如果func1 用的很多,那么选解法二
如果func2 用的很多,那么选解法一
如果都用的很多, distributed evenly
那么,解法二会更好。因为他的表现更加均衡,没有短板。
Anyway, Good luck, Richardo! — 09/05/2016