LeetCode:Two Sum

简介:

Given an array of integers, find two numbers such that they add up to a specific target number.

The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.

You may assume that each input would have exactly one solution.

Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2

注意:元素可能有重复

最简单的做法就是一个两重循环,时间复杂度是O(n^2),下面提供两种更高效的解法

算法1:

将数组的数组映射到哈希表,key是元素的值,value是该值在数组中的索引。考虑到数组中元素有重复,我们使用STL中的unordered_multimap, 它可以允许重复的key存在。映射以后,对于数组中的某个元素num,我们只要在哈希表中查找num2 = target-num。需要注意的是在哈希表中找到了num2,并不一定代表找到了题目要求的两个数,比如对于数组2 7 11 15,target = 4,当num = 2时,num2 = target-num = 2,此时num2可以在哈希表中找到,但是num和num2指向的是同一个元素。因此当num2 = num时,在哈希表找到num2的同时,还需要保证哈希表中num2的个数>=2。

该算法时间复杂度为O(n)

复制代码
 1 class Solution {
 2 public:
 3     vector<int> twoSum(vector<int> &numbers, int target) {
 4         int n = numbers.size();
 5         vector<int> res;
 6         unordered_multimap<int, int> umap;
 7         for(int i = 0; i < n; i++)
 8             umap.insert(make_pair(numbers[i], i));
 9         for(int i = 0; i < n; i++)
10         {
11             auto range = umap.equal_range(target - numbers[i]);
12             if(range.first != umap.end())//found
13             {
14                 if(numbers[i] != target - numbers[i])
15                 {
16                     auto range2 = umap.equal_range(numbers[i]);
17                     res.push_back(min(range.first->second, range2.first->second) + 1);
18                     res.push_back(max(range.first->second, range2.first->second) + 1);
19                 }
20                 else
21                 {
22                     auto ite = ++(range.first);
23                     if(ite != range.second)
24                     {
25                         auto range2 = umap.equal_range(numbers[i]);
26                         res.push_back(min(ite->second, range2.first->second) + 1);
27                         res.push_back(max(ite->second, range2.first->second) + 1);
28                     }
29                 }
30             }
31         }
32         return res;
33     }
34 };
复制代码

算法2:

首先对数组按小到大排序,然后设定两个指针head、tail分别指向排序好的数组的首尾:                                     本文地址

  • 如果两个指针对应的元素和等于target,那么找到了
  • 如果两个指针对应的元素和小于target,那么需要增加和的大小,则把head指针向后移动
  • 如果两个指针对应的元素和大于target,那么需要减少和的大小,则把tail指针向前移动
  • head赶上tail指针时,结束

由于本题中需要返回最后找到的数对的索引,因此,排序是我们不移动原来数组的元素,只是把元素的的索引放到一个新的数组,对这个新的索引数组排序

复制代码
 1 class Solution {
 2 private:
 3     static vector<int> *numbersCopy;
 4     static bool cmp(int idx1, int idx2)
 5     {
 6         return (*numbersCopy)[idx1] < (*numbersCopy)[idx2];
 7     }
 8 public:
 9     vector<int> twoSum(vector<int> &numbers, int target) {
10         numbersCopy = &numbers;
11         int n = numbers.size();
12         vector<int> res;
13         vector<int> idx(n);
14         for(int i = 0; i < n; i++)
15             idx[i] = i;
16         sort(idx.begin(), idx.end(), Solution::cmp);
17         
18         int head = 0, tail = n-1;
19         while(head < tail)
20         {
21             if(numbers[idx[head]] + numbers[idx[tail]] < target)
22                 head++;
23             else if(numbers[idx[head]] + numbers[idx[tail]] > target)
24                 tail--;
25             else //found
26             {
27                 res.push_back(min(idx[head], idx[tail]) + 1);
28                 res.push_back(max(idx[head], idx[tail]) + 1);
29                 break;
30             }
31         }
32         
33         return res;
34     }
35 };
36 vector<int> * Solution::numbersCopy = NULL;
复制代码

 






本文转自tenos博客园博客,原文链接:http://www.cnblogs.com/TenosDoIt/p/3647244.html,如需转载请自行联系原作者

目录
相关文章
|
存储 缓存 算法
LeetCode刷题---Two Sum(一)
LeetCode刷题---Two Sum(一)
Leetcode 4. Median of Two Sorted Arrays
题目描述很简单,就是找到两个有序数组合并后的中位数,要求时间复杂度O(log (m+n))。 如果不要去时间复杂度,很容易就想到了归并排序,归并排序的时间复杂度是O(m+n),空间复杂度也是O(m+n),不满足题目要求,其实我开始也不知道怎么做,后来看了别人的博客才知道有个二分法求两个有序数组中第k大数的方法。
41 0
|
存储 C++ Python
LeetCode刷题---Add Two Numbers(一)
LeetCode刷题---Add Two Numbers(一)
|
存储 算法 安全
LeetCode - #2 Add Two Numbers
我们社区从本期开始会将顾毅(Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。
LeetCode - #2 Add Two Numbers
|
存储 算法 安全
LeetCode - #1 Two Sum
我们社区从本期开始会将顾毅(Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。
LeetCode - #1 Two Sum
LeetCode 350. Intersection of Two Arrays II
给定两个数组,编写一个函数来计算它们的交集。
78 0
LeetCode 350. Intersection of Two Arrays II
|
Python
LeetCode 349. Intersection of Two Arrays
给定两个数组,编写一个函数来计算它们的交集。
73 0
LeetCode 349. Intersection of Two Arrays
LeetCode 160. Intersection of Two Linked Lists
编写一个程序,找到两个单链表相交的起始节点。
71 0
LeetCode 160. Intersection of Two Linked Lists
LeetCode 167 Two Sum II - Input array is sorted(输入已排序数组,求其中两个数的和等于给定的数)
给定一个有序数组和一个目标值 找出数组中两个成员,两者之和为目标值,并顺序输出
89 0
LeetCode 21. 合并两个有序链表 Merge Two Sorted Lists
LeetCode 21. 合并两个有序链表 Merge Two Sorted Lists