题目
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/two-sum
分别用暴力枚举和哈希算法两种方法解决问题
一:暴力枚举法
用两个for循环依次遍历数组中的每一个元素找出与之相加等于target的数值,外层for循环是用来遍历数组元素,内层for循环用来寻找与之对应相加为target的数值,该方法时间复杂度为O(n²)
代码如下:
package com.itheima.suanfa;
//力扣第1题两数之和枚举法
import java.util.Arrays;
public class Charter0 {
public int[] twoSum(int[] nums, int target) {
int[] ans = new int[2];
//遍历数组每一个元素
for(int i = 0;i < nums.length;i++)
//寻找与该数组元素对应相加为target的数值
for(int j = i+1;j <nums.length;j++) {
if(nums[i]+nums[j] == target) {
ans[0] = i;
ans[1] = j;
break; //因为每种输入只会对应一种答案,所以得到结果后可直接跳出循环 (代码优化,可减少占用的内存)
}
}
return ans;
}
public static void main (String[] args) {
int[] nums = {3, 2, 4};
int target = 6;
Charter0 c = new Charter0();
int[] sum = c.twoSum(nums,target);
System.out.println("[" + sum[0] + "," + sum[1] + "]");
}
}
运行结果
57 / 57 个通过测试用例
状态:通过
执行用时: 45 ms
内存消耗: 41.6 MB
很显然该方法时间复杂度过大并不理想
二:哈希算法
运用哈希表先将遍历到的数组元素存储起来,查看target减去目前遍历到的元素是否等于先前哈希表中已有的元素,如果等于则返回这两个元素的索引到主函数即可,该方法时间复杂度为O(n)
代码如下:
package com.itheima.suanfa;
//力扣第1题两数之和哈希算法
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class Charter1 {
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
int[] ans = new int[2];
for(int i = 0;i < nums.length;i++) {
//查找哈希表,如果表中存在和现在访问的值配对的数值,则返回对应哈希表的key到主函数
if(map.containsKey(target-nums[i])) {
ans[0] = map.get(target-nums[i]);
ans[1] = i;
break; //直接跳出循环,因为不存在两种答案的情况,此时运行时间可打败99.30%的用户
}
map.put(nums[i], i); //把数组里的数值按顺序填充到哈希表
}
return ans;
}
public static void main (String[] args) {
int[] nums = {3, 2, 4};
int target = 6;
Charter1 c = new Charter1();
int[] sum = c.twoSum(nums,target);
System.out.println("[" + sum[0] + "," + sum[1] + "]");
}
}
运行结果
57 / 57 个通过测试用例
状态:通过
执行用时: 1 ms
内存消耗: 41.5 MB
很显然该方法时间能大大减少运行时间