1.两数之和

1. 两数之和

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

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

示例:

给定 nums = [2, 7, 11, 15], target = 9

 

因为 nums[0] + nums[1] = 2 + 7 = 9

所以返回 [0, 1]

解决方案

方法一:暴力法

暴力法很简单。遍历每个元素 x,并查找是否存在一个值与 target相等的目标元素。

 1 // 暴力法
 2 class Solution {
 3 public:
 4     vector<int> twoSum(vector<int>& nums, int target) {
 5         int size = nums.size();
 6         
 7         for(int i=0;i<size-1;++i)
 8             for (int j = i+1; j < size; ++j)
 9             {
10                 if (nums[i] + nums[j] == target)
11                     return vector<int> {i, j};
12             }
13         return vector<int> {0, 0};
14     }
15 };

 

  

复杂度分析:

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

空间复杂度:O(1)。

 

运行时间:

96ms

 

 

方法:一遍哈希表

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

 1 // 最优解
 2 // 使用哈希表进行一次遍历
 3 class Solution {
 4 public:
 5     vector<int> twoSum(vector<int>& nums, int target) {
 6         int size = nums.size();
 7         map<int, int> Map;
 8 
 9         Map.insert(make_pair(target - nums[0], 0));
10         for (int i = 1; i < size; ++i)
11         {
12             map<int, int>::iterator iter = Map.find(nums[i]);
13             if (iter != Map.end())
14             {
15                 int index = iter->second;
16                 if (index != i)
17                     return vector<int> {index,i};
18             }
19             Map.insert(make_pair(target - nums[i], i));
20         }
21         return vector<int>{0,0};
22     }
23 };

 

  

复杂度分析:

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

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

 

运行时间:

8ms

 

 

补充

C++ map注意事项:

1、在map中,由key查找value时,首先要判断map中是否包含key。

2、如果不检查,直接返回map[key],可能会出现意想不到的行为。如果map包含key,没有问题,如果map不包含key,使用下标有一个危险的副作用,会在map中插入一个key的元素,value取默认值,返回value。也就是说,map[key]不可能返回null。

3、map提供了两种方式,查看是否包含key,m.count(key),m.find(key)。

4、m.count(key):由于map不包含重复的key,因此m.count(key)取值为0,或者1,表示是否包含。

5、m.find(key):返回迭代器,判断是否存在。

6、对于下面的场景,存在key就使用,否则返回null,有下面两种写法:

 

if(m.count(key)>0)

{

     return m[key];

}

return null;

iter = m.find(key);

if(iter!=m.end())

{

    return iter->second;

}

return null;

 

 

 

 

 

 

 

 

 

 

 

 

 

这里需要注意:前一种方法很直观,但是效率差很多。因为前面的方法,需要执行两次查找。因此,推荐使用后一种方法。

7、对于STL中的容器,有泛型算法find(begin,end,target)查找目标,map还提供了一个成员方法find(key)

posted @ 2018-10-21 11:02  阿卡阿卡啊卡卡卡  阅读(169)  评论(0编辑  收藏  举报