【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(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;
            }
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值