【LeetCode刷题记录】Two Sum

来源:互联网 发布:便宜质量好的淘宝店 编辑:程序博客网 时间:2024/06/11 17:20

题目

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(1),但时间复杂度是O(n^2),在测试中遇到稍大一点规模的数组,必然会超时。代码如下:

vector<int> twoSumTLE(vector<int>& nums, int target)    vector<int> index(2);    int sz = nums.size();    int i, j;    for (i=0; i<sz; i++) {        for (j=i+1; j<sz; j++) {            if (nums[j] == target-nums[j]) {                index[0] = i+1;                index[1] = j+1return index;            }        }            }}
方法二:

因为是在分类Hash Table找的题,所以自然而然地想到了map或hash。前后尝试了map、hash_map和unordered_map三种,map和unordered_map引入using namespace std下的#include<map>#include<unordered_map>,而hash_map则引入using namespace __gun_cxx下的#include<ext/hash_map>。三种数据结构的使用方法差不多,下面以hash_map为例。

顾名思义,map或hash所做的就是key到value的映射。如果你只想保存key和value的对应关系,可以直接使用形如”hash[key]=value“产生映射;但如果你只有key,想产生和key具有某种关系的value,就需要自己实现哈希函数,使用形如“value=hash_function(key)”产生映射。

这里的思路也不难:首先,使用hash_map建立数组中所有元素的值到下标的映射,即indexMap[nums[i]]=i。然后建立一个循环,以第一个数组的第一个元素为当前元素,得到目标数减去当前元素的差值。把这个差值作为key,用hash_map的find方法去搜索,如果找到则返回两个数的下标,没有则继续下一个元素。

我在解题时因为粗心遇到了两个坑:一是最开始从hash_map开始遍历,而不是从原数组遍历。如果数组中的元素都不相同确实没有影响,每次都能根据差值找到唯一的数;但如果数组中的元素存在相同就有问题了,因为相同元素是以桶元素的形式保存在hash_map中。而且,是以头插法的方式插入到桶中。所以,如果去遍历hash_map,那么当两个数相同时,就只能根据差值找到一个数。另一个坑是忘记判断返回值下标大小,因为题目要求下标小的放在返回vector的前面。

最后,终于从坑中爬出来,AC了。代码如下:

class Solution {public:    vector<int> twoSum(vector<int>& nums, int target) {        vector<int> result(2); // store result        int sz = nums.size();        int i;        map<int, int> indexMap; // map to store nums and its index        for (i=0; i<sz; i++)            indexMap[nums[i]] = i+1;        for (i=0; i<sz; i++) {            if (indexMap.find(target-nums[i]) != indexMap.end()) {// search the other number                result[0] = i+1;                result[1] = indexMap[target-nums[i]];                if (result[0] == result[1])                    continue;                if (result[0] > result[1]) {                    result[0] ^= result[1];                    result[1] ^= result[0];                    result[0] ^= result[1];                }                return result;            }        }    }};
0 0
原创粉丝点击