[leetcode]兩數之和

給定一個整數數組 nums 和一個目標值 target,請你在該數組中找出和爲目標值的那 兩個 整數,並返回他們的數組下標。java

你能夠假設每種輸入只會對應一個答案。可是,你不能重複利用這個數組中一樣的元素。node

示例:數組

給定 nums = [2, 7, 11, 15], target = 9

由於 nums[0] + nums[1] = 2 + 7 = 9
因此返回 [0, 1]

官方解答:
public int[] twoSum(int[] nums, int target) {
    Map<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < nums.length; i++) {
        map.put(nums[i], i);
    }
    for (int i = 0; i < nums.length; i++) {
        int complement = target - nums[i];
        if (map.containsKey(complement) && map.get(complement) != i) {
            return new int[] { i, map.get(complement) };
        }
    }
    throw new IllegalArgumentException("No two sum solution");
}

  官方這樣的作法時間複雜度是o(n),可是for循環裏帶containKey怎麼會是o(n)呢?指針

  原來map.containKey()的複雜度能夠看作o(1):code

if ((tab = table) != null && (n = tab.length) > 0 &&
            (first = tab[(n - 1) & hash]) != null) {
            // 直接命中
            if (first.hash == hash && // always check first node
                ((k = first.key) == key || (key != null && key.equals(k))))
                return first;
            // 未命中
            if ((e = first.next) != null) {
                if (first instanceof TreeNode)
                    return ((TreeNode<K,V>)first).getTreeNode(hash, key);
                do {
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        return e;
                } while ((e = e.next) != null);
            }
        }

  

  1. 指針first指向那一行數組的引用(那一行數組是經過table下標範圍n-1和key的hash值計算出來的),若命中,則經過下標訪問數組,時間複雜度爲O(1)
  2. 若是沒有直接命中(key進行hash時,產生相同的位運算值),存儲方式變爲紅黑樹,那麼遍歷樹的時間複雜度爲O(n)。

blog

  另外,由於hashMap以key存hash,value是根據key所得。因此containValue()的時間複雜度爲O(n),和containKey()不一樣。get

相關文章
相關標籤/搜索