leetcode系列:twosum问题

题目描述:
输入:一个数组(nums[]),一个数(target)
输出:从数组中取两个数使得两数之和等于target,输出这两个数的下标

1,一开始的想法是,使用两重循环直接一一遍历,穷举出这两个数,并得到他们的下标

 public static int[] twoSum1(int[] nums, int target) {
        int[] tuple = new int[2];
        for (int i = 0; i < nums.length; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[i] + nums[j] == target) {
                    tuple[0] = i;
                    tuple[1] = j;
                    return tuple;
                }
            }
        }
        //参数错误的异常
        throw new IllegalArgumentException();
    }

这个算法的时间复杂度是O(n^2),并不是很理想

2,我们学过map,如果我们把key设为数组中的数,value设为下标,hash索引的复杂度是常数级别的,在已知一个数的情况下是很容易从hashmap中得到这个数以及这个数的位置的

public static int[] twoSum2(int[] nums, int target) {
        Map<Integer, Integer> integerMap = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            integerMap.put(nums[i], i);
        }
        for (int i = 0; i < nums.length; i++) {
            int temp = target - nums[i];
            if (integerMap.containsKey(temp)) {
                return new int[]{i, integerMap.get(temp)};
            }
        }
        throw new IllegalArgumentException();
    }

这时候算法的时间复杂度就降下来了变成了O(n)

这个问题还可以脱战成三个数或者四个数的问题,虽然数值增加了 ,但是方法的思想都是一样的,可以利用两个数的问题来解决。

总结:从这个题目中领悟到我们在做下标和数值这类问题的时候可以尝试使用hashmap来解决,因为这个过程中的查找是常数级别的,遇到这类问题也要很好的尝试往数学中的集合上靠,这样才能把算法的时间复杂度降下来。

点赞