算法:1、两数之和

问题

给定一个整数数组nums和一个目标值,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标,你可以假设每种输入只会对应一个答案,但是,数组中同一个元素不能使用两遍。

实例:

给定 nums = [2,7,11,15], target=9
因为nums[0]+nums[1] = 2+7=9
所以返回[0,1]
class Solution {
     
    public int[] twoSum(int[] nums, int target) {
     
    
    }
}

方法一:暴力解法

暴力解法很简单,就是遍历每个元素x,判断是否存在满足条件的值(x+y=target)

public int[] twoSum(int[] nums, int target) {
     
        int[] rturn = new int[2];
        for(int i=0; i<nums.length-1;i++){
     
            for(int j=i+1; j<=nums.length-1; j++){
     
                if(nums[i] + nums[j] == target){
     
                    rturn[0] = i;
                    rturn[1] = j;
                }
            }
        }
        return rturn;
    }

复杂度分析

  • 时间复杂度:O( n 2 n^2 n2)
    对每一个元素,我们试图通过遍历数组的其余部分来寻找他所对应的目标元素,这将耗费O(n)的时间。两个for循环嵌套。

方法二:两次哈希表

使用哈希表来解决问题:
一个简单的实现使用两次迭代。在第一次迭代中,我们将每个元素的值和他的索引添加到表中,然后,在第二次迭代中,我们将检查每个元素所对应的目标值 ( t a r g e t − n u m s [ i ] ) (target-nums[i]) targetnums[i]是否存在于表中,注意:改目标值不能是 n u m s [ i ] nums[i] nums[i]本身。

class Solution {
     
    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 ) O(n) O(n)
    我们把包含n个元素的列表分开遍历了两次,一次最多只有一个for循环。

方法三:一次哈希表

在进行迭代并将元素插入到表中的同时,我们还可以检查表中是否已经存在当前元素所对应的目标元素。如果它存在,那我们已经找到 了对应的解。

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

参考

两数之和

讨论

你认真看过代码之后你会发现 在 转存的时候,使用的值作为表的key,就是下面这句话 map.put(nums[i], i);
比如像{2,2,3,4,5}这样的数组,大多数可能认为会丢掉key为2,value为0的值。
你可以用数据测试,打断点,这个有点隐秘。他会“隐式”调用 这个值,现在暂时还没有找到好的表述词。
算法:1、两数之和_第1张图片

你可能感兴趣的:(算法题,哈希表)