【LeetCode01】

122 阅读2分钟

在学校也安顿下来了,虽然目前是starting extremely late的情况,但是比没有开始好

接下来希望能频繁更新,坚持刷题,争取每道题都写一篇update记录学习到的东西

Leetcode01:TwoSum

方法一:暴力法 最简单最容易想到的,缺点是时间复杂度n^2

方法二:HashMap

HashMap在一般情况下认为查找复杂度O(1)

官方题解分一遍哈希表和两遍哈希表的,写了两遍的为:

public static int[] twoSum(int[] nums, int target){
    //practice using hashmap
    HashMap<Integer,Integer> mapping = new HashMap<>();
    for(int i=0;i<nums.length;i++){
        mapping.put(nums[i],i);
    }
    for(int i = 0;i<nums.length;i++){
        int diff = target-nums[i];
        if(mapping.containsKey(diff) && mapping.get(diff)!=i) return new int[] {i,mapping.get(diff)};
        
    }
    throw new IllegalArgumentException("no matching pairs");
    
}

一遍哈希表的方法我并不能直接想到,它的精妙之处在于尽管在一些情况下如果数组中有nums[i]+nums[j]==target但当循环到i时nums[j]并没有被加入到哈希表中,但是由于有:

target-nums[i]==nums[j] 同时就有 target-nums[j]==nums[i]

这样后一个数被添加的时候就可以满足条件并返回i,j

写一下代码:

public static int[] oneHashtwoSum(int[] nums, int target){
    HashMap<Integer,Integer> mapping = new HashMap<>();
    for(int i=0;i<nums.length;i++){
        int diff = target-nums[i];
        if(mapping.containsKey(diff)&&mapping.get(diff)!=i) return new int[] {i,mapping.get(diff)};
        mapping.put(nums[i],i);
    }
    throw new IllegalArgumentException("no matching pairs");
}

一些细节:

1.哈希表在这个题中最大的好处是可以用一个.containsKey()方法查找所有已有的key(当然了也有.containsValue()),这样就避免了暴力解法中对每个值进行全数组的查找

2.哈希表刻意将数组索引放在value,值放在key处,是因为这样得到索引来判断是否重复使用时.get()函数最快最方便,反过来使用value找key很麻烦.

3.在一遍哈希表方法中选择先判断再添加,我个人认为如果反之会需要每次判断.containsKey()为真,后判断!=i为假,两次判断,而先判断后添加只有一次。

有疑惑的地方:

hashmap中key重复的情况:新的value取代旧的value?

测试后的确如此