两数之和

给定一个整数数组 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]

解题思路:

1.这道题我第一眼的思路就是遍历所有可能。我先创建一个长度与数组nums相同的数组result。

2.然后将数组nums内能相加等于target的下标存入result内,并且用num记录result的真实长度(result一定插入不满,剩余的默认值为0)。

3.最后再创建一个数组result1,通过真实长度num,将result复制到result1中返回。这种方法算是最笨的方法了,因为对每个数都进行了比较,等比较完才进行返回。

 

解:

public static int[] twoSum(int[] nums, int target) {
    int result[] = new int[nums.length];
    int num = 0;
    for(int i=0;i<nums.length;++i) {
        for (int j=0;j<nums.length;j++) {
            if (nums[i]+nums[j] == target && i!=j) {
                result[num++] = i;
                break;
            }
        }
    }
    int result1[] = new int[num];
    for (int i=0;i<num;++i) {
        result1[i] = result[i];
    }
    return result1;
}

  

官方解:
枚举法

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int n = nums.length;
        for (int i = 0; i < n; ++i) {
            for (int j = i + 1; j < n; ++j) {
                if (nums[i] + nums[j] == target) {
                    return new int[]{i, j};
                }
            }
        }
        return new int[0];
    }
}

  

哈希表法:

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> hashtable = new HashMap<Integer, Integer>();
        for (int i = 0; i < nums.length; ++i) {
            if (hashtable.containsKey(target - nums[i])) {
                return new int[]{hashtable.get(target - nums[i]), i};
            }
            hashtable.put(nums[i], i);
        }
        return new int[0];
    }
}

  

1.枚举法对比官方解,题目中是只要找出一组下标相加等于target即可,而我是找出所有下标能够相加等于target,不过本质也差不多都是双循环,复杂度为N2。

2.哈希表法的理解:我认为就是利用map集合的的便利,查询的方法就是对每个元素进行遍历,判断map里面是否存在key=target-nums[i],不存在则将当前(num[i],i)存入map。
过程就是第一次我先查有没有(初始化map肯定是啥也没有),没有则将(num[0],0)存入map,第二次则判断(key=target-num[1]),此时map里面就只有一个num[0],如果num[0]+num[1]=target,则取出map.get(target-num[i])。

3.思考一下为什么哈希表为什么可以降低复杂度?
答:不管是双循环还是哈希表,总共要遍历n-1的元素,所有元素遍历的次数加起来为n-1+n-2+n-3+...+1,在枚举法中i的循环为了遍历每个元素这个是必须的,j的循环针对当前元素,遍历其他元素(当前元素为n,则遍历剩下n-1个数的元素)与当前元素相加是否为target。通俗点讲,一个长度为n的数组nums,我从最后一元素开始比较(当前元素为nums[n-1]),我往前比较需要n-1次(因为n个元素,从最后一个元素开始,与剩下的元素比较就是n-1次),比较完了之后向前移动一个,当前元素为nums[n-2],我向前比较也需要比较n-2次,直到移动到第二个元素,只需要向前比较1次。而哈希表法就是把这个过程倒过来了,利用map集合键值对的特性(对于目前的我还是有点难想到)。





posted @ 2022-11-04 12:56  陈阿  阅读(64)  评论(0)    收藏  举报