【LeetCode】01 Two Sum与HashMap

给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。

你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。

示例:

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

因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]

解法1:暴力求解

class Solution {
    public int[] twoSum(int[] nums, int target) {
        for (int i = 0;i < nums.length;i++){
            for (int j = i + 1;j < nums.length;j++){
                if (nums[i] + nums[j] == target){
                    return new int[]{i,j};
                }
            }
        }
        throw new IllegalArgumentException("No two sum solution");
    }
}

解法2:利用HashMap

  • 解法1的问题是,我们最后要的答案是数组的下标,而在数组中我们只能通过下标访问到元素。
  • 如果我们只能通过下标访问到元素,我们需要对每对可能出现的值对组合进行遍历,那么最后时间复杂度必然是O(n^2)
  • 而如果我们可以通过元素访问下标,遍历一遍数组,对于每个元素,都只需要进行一个操作:在已检查过的元素里查询是否有符合条件的元素,找到则返回它的下标

换句话说,这道题的思路其实只有一种:对每一个数组中的元素,查询某条件下的另一元素的下标
第一个循环,两种方法是一致的,所以至少O(n)
数组:我知道我有一堆元素,我不知道他们是啥。查询的思路孜然是再遍历一次之前的数组元素,找到目标元素。
HashMap:我知道我有什么元素。那么我既然知道你要找的数组元素大小是多少,直接查看键值对里有没有这个键就好了。

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> map = new HashMap<>();
        int i;
        int complement;
        for (i = 0;i < nums.length;i++){
            complement = target - nums[i];
            if(map.containsKey(complement)){
                return new int[] {map.get(complement), i};
            }
            map.put(nums[i], i);
        }
        throw new IllegalArgumentException("!!!");
    }
}

这道题的目的在于,告诉我们有一种数据结构(Map)可以实现两种结构间的一对一访问,而其中的佼佼者,叫做HashMap(用TreeMap试验了一下,速度比HashMap慢,时间复杂度应该是O(nlogn))

猜你喜欢

转载自blog.csdn.net/qq_36269372/article/details/83316963
今日推荐