GitHub地址
题目
- 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。
- 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。
示例
- 给定 nums = [2, 7, 11, 15], target = 9
- 因为 nums[0] + nums[1] = 2 + 7 = 9
- 所以返回 [0, 1]
代码
哇,这题是一道很经典的题目,虽然简单,但是还是难道我了,一开始我一直在想时间复杂度为O(n),然后有个啥事打断我思路了,回来就直接写了一个暴力遍历的方法,就是下面的啦
public static int[] twoSum(int[] nums, int target) {
int[] temp = new int[2];
boolean flag = false;
for (int i = 0; i < nums.length; i++) {
if (flag)
break;
for (int j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] == target) {
temp[0] = i;
temp[1] = j;
flag = true;
break;
}
}
}
return temp;
}
然后只击败了14%的人,我想想不能就这么简单就放过了,所以又想了下一种方法,用空间换时间的方法。
public static int[] twoSum(int[] nums, int target) {
HashMap<Integer, Integer> map = new HashMap<>(nums.length);
int[] res = new int[2];
for (int i = 0; i < nums.length; ++i) {
map.put(nums[i], i);
}
for (int i = 0; i < nums.length; ++i) {
int sub = target - nums[i];
if (map.containsKey(sub) && map.get(sub) != i) {
res[0] = i;
res[1] = map.get(sub);
break;
}
}
return res;
}
最后看了第一名的算法,恕我愚钝,硬是没看懂 :),有人能给我解答一波就好了。。。
public static int[] twoSum(int[] nums, int target) {
int[] res = new int[2];
if (nums == null || nums.length < 2)
return res;
int max = nums[0];
int min = nums[0];
for (int i = 1; i < nums.length; i++) {
if (max < nums[i])
max = nums[i];
if (min > nums[i])
min = nums[i];
}
int[] index = new int[max - min + 1];
int other;
for (int i = 0; i < nums.length; i++) {
other = target - nums[i];
if (other < min || other > max) {
continue;
}
if (index[other - min] > 0) {
res[0] = index[other - min] - 1;
res[1] = i;
return res;
}
index[nums[i] - min] = i + 1;
}
return res;
}