算法习题篇之Twosum

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/aizaiee/article/details/82991305

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,要是有负数怎么办,好了,这个很简单的题就分析到这里了。

猜你喜欢

转载自blog.csdn.net/aizaiee/article/details/82991305