两数之和

需求

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

示例

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

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

解题

  第一次做类似的算法题,个人算法水平比较渣,只能想到暴力破解法。也就是下文的解法一。但是还有更快速的两遍哈希表法和一遍哈希表法。

  解法一:暴力破解,时间复杂度:O(n^2),空间复杂度:O(1)。

    // 解法一:暴力破解
    // 思路:将数组中的每一个元素,对其余部分进行遍历,找到目标值即可
    public static 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};
                }
            }
        }
        return null;
    }

  解法二:两遍哈希表,空间换时间。时间复杂度:O(n),空间复杂度:O(n)。

    // 解法二:两遍hash表
    // 思路:1、将数组加入到map中
    //       2、如果map中存在containsNum + num[i]= target,则找到目标值
    public static int[] twoSum2(int[] nums, int target) {
        HashMap<Integer, Integer> map = new HashMap<>(nums.length);
        for (int i = 0; i < nums.length; i++) {
            map.put(nums[i], i);
        }

        for (int i = 0; i < nums.length; i++) {
            int containsNum = target - nums[i];
            if (map.containsKey(containsNum) && map.get(containsNum) != i) {
                return new int[]{i, map.get(containsNum)};
            }
        }

        return null;
    }

  解法三:一遍哈希表,空间换时间,减少遍历哈希表的次数。时间复杂度:O(n),空间复杂度:O(n)。

    // 解法三:一遍hash表
    // 思路:边加入数据,边判断:如果map中存在containsNum + num[i]= target,则找到目标值
    public static int[] twoSum3(int[] nums, int target) {
        Map<Integer, Integer> map = new HashMap<>();

        for (int i = 0; i < nums.length; i++) {
            int containsNum = target - nums[i];
            if (map.containsKey(containsNum)) {
                return new int[]{map.get(containsNum), i};
            }
            map.put(nums[i], i);
        }

        return null;
    }

参考:力扣(LeetCode)官方解析

posted @ 2020-04-20 15:29  一马关月  阅读(125)  评论(0编辑  收藏  举报