题目:

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.

翻译:

给定一组整数,两个数字的返回索引,它们的和会等于一个特定的数。

您可能假设每个输入都有一个解决方案,但是你不能使用同一个元素两次。(好吧一开始英语弱鸡的我也没懂,后来编程的时候想到的解释:同一个数不能通过自加而得到目标数)

第一遍编写:74ms

  1. class Solution {
  2. public int[] twoSum(int[] nums, int target) {
  3. Set<Integer> resultSet = new HashSet<Integer>();
  4. for (int i = 0; i < nums.length; i++) {
  5. for (int j = i + 1; j < nums.length; j++) { // 就是这里想到一个数自加,所以应该从i+1开始。
  6. if (nums[i] + nums[j] == target) {
  7. resultSet.add(i);
  8. resultSet.add(j);
  9. }
  10. }
  11. }
  12. int[] result = new int[resultSet.size()];
  13. for (int i = 0; i < result.length; i++) {
  14. result[i] = (Integer) resultSet.toArray()[i];
  15. }
  16. return result;
  17. }
  18. }

好吧,第一次刷题,隐隐小激动,一开始确实没看清题目。。

看清题目后第一次:46ms    时间复杂度:O(n2)

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

自己看着都觉得菜的很。。竟然用了嵌套for。。

下面是参考答案:12ms    时间复杂度:O(n)

  1. public int[] twoSum(int[] nums, int target) {
  2. Map<Integer, Integer> map = new HashMap<Integer, Integer>();
  3. int[] result = new int[2];
  4.  
  5. for (int i = 0; i < nums.length; i++) {
  6. if (map.containsKey(target - nums[i])) {
  7. result[0] = map.get(target - nums[i]);
  8. result[1] = i; // 此时 i 对应的元素还没有放进去。
  9. return result;
  10. }
  11. map.put(nums[i], i);
  12. }
  13. return result;
  14. }

原来用了HashMap来定位两者有某种关系的数。。快了一倍多。。

结论:

当需要使用嵌套for循环来查找或者定位的时候,尽量优先考虑是否能使用Map(存储每一个值作为key,相应下标作为value)

使用  map.containsKey(__) 方法来进行定位

2018-1-8更新:今天做到3sum想到和这里的2sum联系,

3sum:求所有的相加为目标值的数组,

2sum:一旦查找到相加为目标值的俩数组则直接返回俩下标,程序直接结束(仅一组)

现在将2sum的题目改为如下:

给定一个n个整数的数组,在数组中找到和为目标值的所有唯一的两个元素组合【注意不是求下标】

注意:答案集不能包含重复的双胞胎。

测试用例:{1,4,-1,2,-1,0}   1     结果:[[0, 1], [-1, 2]]

     {3,2,3,4,1,4,5,5}  8     结果:[[4, 4], [3, 5]]

Code1:时间复杂度:O(N)    【其实应该是Arrays.sort(num)的复杂度】

  1. public static List<List<Integer>> twoSumAll(int[] num, int target) {
  2. Arrays.sort(num); // 将所有相同元素挨在一起
  3. List<List<Integer>> res = new LinkedList<List<Integer>>();
  4. Set<Integer> set = new HashSet<Integer>(); // 不需要下标,并且需要元素唯一,所以采用Set
  5. for (int i = 0; i < num.length; i++) {
  6. if (set.contains(target - num[i])) {
  7. res.add(Arrays.asList(target - num[i], num[i]));
  8. set.remove(target - num[i]); // 防止后续重复元素继续利用此值(因为已经排序,后面不会再有前面的值,不需要再remove(num[i]))
  9. }
  10. set.add(num[i]);
  11. }
  12. return res;
  13. }

此方法仍然采用上面2sum的思想,利用contains()函数减少一次循环,注意Set的remove使答案避免了”双胞胎数组“

下面采用第15题的3sum的‘’双指针相向移动‘’的思想进行算法编写:

Code2:时间复杂度:O(N)   【其实应该是Arrays.sort(num)的复杂度】

  1. public static List<List<Integer>> twoSumAll2(int[] num, int target) {
  2. Arrays.sort(num);
  3. List<List<Integer>> res = new LinkedList<List<Integer>>();
  4. int left = 0;
  5. int right = num.length - 1;
  6. while (left < right) {
  7. if (num[left] + num[right] == target) {
  8. res.add(Arrays.asList(num[left], num[right]));
  9. while (left < right && num[left] == num[left+1]) left++;
  10. while (left < right && num[right] == num[right-1]) right--;
  11. left++;
  12. right--;
  13. } else if (num[left] + num[right] < target) {
  14. left++;
  15. } else {
  16. right--;
  17. }
  18. }
  19. return res;
  20. }

双指针相向移动:利用了  已排序数组  和  所查找的两个数的和为定值  这两个性质

        这两个性质如果联合一起用的话………………duang!!!

        在已排序数组两端指针所指数之和如果小于目标值,只需要移动左边的指针,否则只需要移动右边的指针

        【还看不懂可以自己打草稿试试,或者看我这个博客:LeetCode第[15]题(Java):3Sum 标签:Array

结论:在求和为目标数时,求下标——HashMap;

            求具体组合值——前后指针;

LeetCode第[1]题(Java):Two Sum 标签:Array的更多相关文章

  1. LeetCode第[18]题(Java):4Sum 标签:Array

    题目难度:Medium 题目: Given an array S of n integers, are there elements a, b, c, and d in S such that a + ...

  2. LeetCode第[15]题(Java):3Sum 标签:Array

    题目难度:Medium 题目: Given an array S of n integers, are there elements a, b, c in S such that a + b + c  ...

  3. LeetCode第[88]题(Java):Merge Sorted Array(合并已排序数组)

    题目:合并已排序数组 难度:Easy 题目内容: Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as ...

  4. LeetCode第[1]题(Java):Two Sum (俩数和为目标数的下标)——EASY

    题目: Given an array of integers, return indices of the two numbers such that they add up to a specifi ...

  5. LeetCode第[46]题(Java):Permutations(求所有全排列) 含扩展——第[47]题Permutations 2

    题目:求所有全排列 难度:Medium 题目内容: Given a collection of distinct integers, return all possible permutations. ...

  6. LeetCode第[16]题(Java):3Sum Closest 标签:Array

    题目难度:Medium 题目: Given an array S of n integers, find three integers in S such that the sum is closes ...

  7. LeetCode第[4]题(Java):Median of Two Sorted Arrays 标签:Array

    题目难度:hard There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median ...

  8. LeetCode第[11]题(Java):Container With Most Water 标签:Array

    题目难度:Medium Given n non-negative integers a1, a2, ..., an, where each represents a point at coordina ...

  9. LeetCode第[5]题(Java):Longest Palindromic Substring 标签:String、动态规划

    题目中文:求最长回文子串 题目难度:Medium 题目内容: Given a string s, find the longest palindromic substring in s. You ma ...

随机推荐

  1. Java的单例模式

    单例模式:单例模式确保其一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 单例模式又分为:懒汉式,饿汉式等; 特点: a.单例只有一个实例. b.必须自己创建自己唯一的实例 c.单例类必须 ...

  2. 转:Natas Wargame Level28 Writeup(EBC加密破解)

    From:http://alkalinesecurity.com/blog/ctf-writeups/natas-28-getting-it-wrong/ Now that I knew it was ...

  3. scott表结构

  4. Python3入门笔记(1) —— windows安装与运行

    Python的设计哲学是"优雅"."明确"."简单".这也是我喜欢Python的理由之一 Python的安装: 1.进入Python官方网站 ...

  5. C 真正理解二级指针

    本文转载自CSDN博主liaoxinmeng,做数据结构时遇到指针方面的问题,想了许久,因此我觉得很有必要复习一下二级指针及其使用 正文如下: 指针是C语言的灵魂,我想对于一级指针大家应该都很熟悉,也 ...

  6. 无 new 构造与链式调用

    无 new 构造 最简单的想法 (function(window) { var jQuery = function() { return new _jQuery(); }; var _jQuery = ...

  7. Eclipse多行同时进行编辑,可编辑或修改相同内容

    使用Shift+Alt+A可以进入Eclipse多行编辑的功能,选中的一部分区域从光标开始处同时进行修改或者插入功能. 再次按下Shift+Alt+A可已退出该编辑模式.

  8. Ant学习笔记

    前言:这段时间在学习Ant,发现这是一个很强大的构建工具.你可能使用了很长一段时间,才发现Ant能做数不完的事.总之,个人觉得,Ant学习门槛低,入门简单,能大概看懂程序,写一些简单的脚本即可,剩下在 ...

  9. 6.Nginx作为负载均衡服务器应用

    案例:Nginx作为负载均衡服务器应用 nginx的负载均衡功能是通过upstream命令实现的,因此他的负载均衡机制比较简单,是一个基于内容和应用的7层交换负载均衡的实现.Nginx负载均衡默认对后 ...

  10. Handwritten Parsers & Lexers in Go (翻译)

    用go实现Parsers & Lexers 在当今网络应用和REST API的时代,编写解析器似乎是一种垂死的艺术.你可能会认为编写解析器是一个复杂的工作,只保留给编程语言设计师,但我想消除这 ...