两数之和
需求
给定一个整数数组 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)官方解析