Leetcode - Shortest Word Distance II

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

    原文作者:Richardo92
    原文地址: https://www.jianshu.com/p/0f1327b21052#comments
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞