1 class Solution {
2 public:
3 /**
4 * @param numbers: An array of Integer
5 * @param target: target = numbers[index1] + numbers[index2]
6 * @return: [index1 + 1, index2 + 1] (index1 < index2)
7 */
8 vector<int> twoSum(vector<int> &numbers, int target) {
9 // write your code here
10 vector<int> result;
11 int size=numbers.size();
12
13 for (int i=0;i<size;i++)
14 {
15
16 for (int j=i+1;j<size;j++)
17 {
18
19 int sum=numbers[i]+numbers[j];
20 if (sum==target)
21 {
22 result.push_back(i);
23 result.push_back(j);
24 return result;
25 }
26 }
27 }
28
29 return result;
30 }
31 };
挑战:
参考 https://www.cnblogs.com/eudiwffe/p/6282635.html
https://www.cnblogs.com/libaoquan/p/6808064.html
C/C++——map的基本操作总结
C++ map注意事项 count与find
常见的思路是:两层for循环,任意两个数组合求其和,判断是否等于给定的target。但这样太慢,需要O(n^2)的时间,O(1)的额外空间。可以反过来思考,假如当前选择了一个数字a,那么为了满足条件,另一个数字b必须满足:b=targe-a,即在数组中寻找是否存在b。
如何快速寻找数组中是否存在一个数字b?假如数组是有序的,可以使用二分查找方法,其查找时间复杂度是O(logn)。然而题目并没给定这个条件。如果对数组排序,首先就要O(nlogn)的时间进行排序,并且排序后,数字的原始下标也要保存,显然需要O(nlogn)的时间以及O(n)的空间,并不是最好的方法。
如何对一个数组进行快速查找一个元素?算法中提供了一种方法——哈希(Hash),即对数组中的每个元素按照某种方法(hash function)计算其“唯一”值id(称为哈希值),存储在新的数组A中(一般称为哈希数组),并且其下标就是这个“唯一”值。那么如果访问A[id]存在,则这个元素存在,否则,原始数组中不存在该元素。由于数组是顺序存储的支持随机访问,所以查找一个元素是否在数组中,只需要O(1)的时间,但是在初始化哈希数组时,需要O(n)的时间和O(n)的空间。对于某些特定应用中,需要快速的时间,而对空间要求不苛刻时,哈希数组是一个非常好的方法。
1 class Solution {
2 public:
3 /**
4 * @param numbers: An array of Integer
5 * @param target: target = numbers[index1] + numbers[index2]
6 * @return: [index1 + 1, index2 + 1] (index1 < index2)
7 */
8 vector<int> twoSum(vector<int> &numbers, int target) {
9 // write your code here
10 vector<int> result;
11 if (numbers.empty())
12 {
13 return result;
14 }
15 int size=numbers.size();
16 map<int,int> hashmap;
17
18 for (int i=0;i<size;i++)
19 {
20 hashmap.insert(pair<int,int>(numbers[i],i));
21 }
22
23 for (int i=0;i<size;i++)
24 {
25 int temp=target-numbers[i];
26 if (hashmap.count(temp)!=0&&hashmap[temp]!=i) //count查找元素出现次数,不为0说明存在;
27 { //hashmap[temp]!=i防止target为某数组元素倍数时返回一样的下标值;
28 result.push_back(i);
29 result.push_back(hashmap[temp]);
30 break;
31 }
32 }
33 if (result[0]>result[1]) //保证当target为数组中两个等值元素的和时下标顺序从小到大;
34 {
35 int t=result[0];
36 result[0]=result[1];
37 result[1]=t;
38 }
39 return result;
40 }
41 };
简单解释下最后一个if语句:
第一次在lintcode上测试时,当数据为[0,3,4,0] 和 0 时输出[3 0],结果错误。
数组中出现两个相同元素值,下标分别为0、3,创建hashmap时,下标为3的0无法插入,所以hashmap中有三对pair,(0,0)(3,1)(4,2)
第二个for循环查找map时,由于target=0,temp=0,在hashmap中count(temp)为1,但hashmap[temp]为0,等于i,不满足要求,循环继续。
直到i=3,temp=0,查找hashmap,找到了key等于0的pair,即(0,0),将下标3、 0插入result中。根据题意,要交换result中两个数据。