leetcode刷题--两数之和(简单)

一、序言

  第一次刷leetcode的题,之前从来没有刷题然后去面试的概念,直到临近秋招,或许是秋招结束的时候才有这个意识,原来面试是需要刷题的,面试问的问题都是千篇一律的,只要刷够了题就差不多了,当然你的基础也要扎实,毕竟在技术面的时候很容易露馅的。

  所以奉劝各位还未毕业,在大三或大二的师弟师妹早点刷题,心里也有底气进入求职大军,毕竟大四开始刷题的话时间上有些太紧了,推荐刷题的话就是牛客和leetcode。

  回归正题,这次记录的是leetcode刷的第一题--两数之和

二、审题

  审题真的很重要,这道题我因为审题和惯性思维的原因导致前两次都编写程序的运行结果不正确。

给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。

你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。

示例:

给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

1、整数数组和一个目标值

    题目中的整数数组是可以有负数正数的,例:{-10,-15,-18,0,9,55}

    目标值可能为整数数组两数之和,意味着可以为正数负数,例:-9 、0 、10

2、同样的元素不能被重复利用

    例:target=6,nums={3,2,4}

    所以返回[1,2],而不是[0,0],3不可以重复利用

三、解题

1、暴力法

  遍历每个元素 xx,并查找是否存在一个值与 target - xtarget−x 相等的目标元素。

直接上代码:

 1 class Solution {
 2     public int[] twoSum(int[] nums, int target) {
 3         int[] down={-1,-1};
 4         
 5         for(int i=0;i<nums.length;i++){
 6             down[0]=i;
 7             for(int j=i+1;j<nums.length;j++){
 8                 if(nums[j]==(target-nums[i])){
 9                     down[1]=j;
10                      return down;
11                 }
12             }
13             
14         }
15         return down;
16         
17     }
18 }

图分析思路:

 

复杂度分析:

  • 时间复杂度:O(n2), 对于每个元素,我们试图通过遍历数组的其余部分来寻找它所对应的目标元素,这将耗费 O(n) 的时间。因此时间复杂度为 O(n2)。

  • 空间复杂度:O(1)。 

2、两遍哈希表

  这个方法我是没有想到的,这需要记录下来,而且我数据结构不太扎实,哈希表也不是很清楚,自己分析总结一下。

  一个简单的实现使用了两次迭代。在第一次迭代中,我们将每个元素的值和它的索引添加到表中。然后,在第二次迭代中,我们将检查每个元素所对应的目标元素(target - nums[i]targetnums[i])是否存在于表中。注意,该目标元素不能是 nums[i]nums[i] 本身!

直接上代码:

 1 public int[] twoSum(int[] nums, int target) {
 2     Map<Integer, Integer> map = new HashMap<>();
 3     for (int i = 0; i < nums.length; i++) {
 4         map.put(nums[i], i);
 5     }
 6     for (int i = 0; i < nums.length; i++) {
 7         int complement = target - nums[i];
 8         if (map.containsKey(complement) && map.get(complement) != i) {
 9             return new int[] { i, map.get(complement) };
10         }
11     }
12     throw new IllegalArgumentException("No two sum solution");

图分析思路:

复杂度分析:

 

  • 时间复杂度:O(n), 我们把包含有 个元素的列表遍历两次。由于哈希表将查找时间缩短到 O(1) ,所以时间复杂度为 O(n)

  • 空间复杂度:O(n), 所需的额外空间取决于哈希表中存储的元素数量,该表中存储了 n 个元素。

3、一遍哈希表

  哈哈哈哈哈哈哈哈哈,这个方法我也搞不太懂,贴上来参考一下吧!!!!

  在进行迭代并将元素插入到表中的同时,我们还会回过头来检查表中是否已经存在当前元素所对应的目标元素。如果它存在,那我们已经找到了对应解,并立即将其返回。

直接上代码:

 1 public int[] twoSum(int[] nums, int target) {
 2     Map<Integer, Integer> map = new HashMap<>();
 3     for (int i = 0; i < nums.length; i++) {
 4         int complement = target - nums[i];
 5         if (map.containsKey(complement)) {
 6             return new int[] { map.get(complement), i };
 7         }
 8         map.put(nums[i], i);
 9     }
10     throw new IllegalArgumentException("No two sum solution");
11 }

复杂度分析:

  • 时间复杂度:O(n), 我们只遍历了包含有 nn 个元素的列表一次。在表中进行的每次查找只花费 O(1) 的时间。

  • 空间复杂度:O(n), 所需的额外空间取决于哈希表中存储的元素数量,该表最多需要存储 个元素。

 

posted @ 2018-11-17 14:03  DJDU  阅读(387)  评论(1编辑  收藏  举报