Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
不到英语四级的水平随便翻译一下,以后的不再详细说明
给一个integer 类型的数组,返回其中两个数的索引,这两个数的和等于target。
你可以认为每一个输入只有一个答案,所以你不能用其中的一个元素两次
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
我的思路很简单,不就是两两配对不重复嘛,就写了两个for循环,然后解决了问题,我的代码如下:
class Solution {
public 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){
int[] twoSum = {i,j};
return twoSum;
}
}
}
return null;
}
}
当然了,瑕疵多的不要不要的,来一发和我一样思路的,比较正规的答案:
public 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[j] == target - nums[i]) {
return new int[] { i, j };
}
}
}
throw new IllegalArgumentException("No two sum solution");
}
-
Time complexity : O(n2). For each element, we try to find its complement by looping through the rest of array which takes O(n) time. Therefore, the time complexity is O(n2)
-
Space complexity : O(1).
-
时间复杂度是n的二次方了,空间复杂度就是一了,
记得好像是算术表达式什么的最后放在右边,效率会有所提高,至于throw不throw的话,应该是没有什么事情的了。
接下来呢,就是干货了,当然是以我现在小白的水平没有想到的东西了:
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
map.put(nums[i], i);
}
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
if (map.containsKey(complement) && map.get(complement) != i) {
return new int[] { i, map.get(complement) };
}
}
throw new IllegalArgumentException("No two sum solution");
}
当然看上去,其实所有的东西我们都会了,但是为什么写的时候用不出来呢,当然是因为用的少了,先把整个数组的索引和值放到一个map集合中,然后就是循环能不能找到和自己配对的另一个map了,当然这里最重要的是这个map.containsKey这个函数的时间复杂度是多少,作者去查了一下https://blog.csdn.net/qq_36442947/article/details/81903542是1到n了,那个value的话就肯定是n的。另一个比较详细的分析https://blog.csdn.net/qingtian_1993/article/details/80763381
-
Time complexity : O(n). We traverse the list containing nn elements exactly twice. Since the hash table reduces the look up time to O(1)O(1), the time complexity is O(n).
-
Space complexity : O(n) The extra space required depends on the number of items stored in the hash table, which stores exactly nn elements.
-
这里一脸懵逼的表示为什么时间复杂度就变成n了呢,最坏的情况去哪里了,真的是一脸懵逼,不过这不耽误我们去使用它,这个的确比上一个方法效率更高,但是相应的,他的空间复杂度也变成了n,所以有舍才有得。
下一个就是这个的改进版了。
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
if (map.containsKey(complement)) {
return new int[] { map.get(complement), i };
}
map.put(nums[i], i);
}
throw new IllegalArgumentException("No two sum solution");
这个就是判断新来的值有没有map里的值和他配对的,如果没有就放到集合里了。
Complexity Analysis:
-
Time complexity : O(n)O(n). We traverse the list containing nn elements only once. Each look up in the table costs only O(1)O(1) time.
-
Space complexity : O(n)O(n). The extra space required depends on the number of items stored in the hash table, which stores at most nn elements.
我的确也想过提高效率的方法,但是我想的方法就有点小儿科了,如果外层循环得到的第一个值是大于target的就放掉了。
相同的这个map的方法就是说,如果是大于target 的就不往map集合里边放了,但是hehe,要是有负数怎么办,好了,这个很简单的题就分析到这里了。