Two Sum

原题链接:https://leetcode.com/problems/two-sum/description/


题目很简单,最开始用的是两层循环的暴力求解,对数组中的每一个数都遍历一次数组即可,如下:

Your runtime beats 17.84 % of cpp submissions.
Runtime: 209 ms
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        for (int i = 0; i < nums.size(); i++) {
            for (int j = i+1; j < nums.size(); j++) {
                if (nums[i] + nums[j] == target) {
                    vector<int> result;
                    result.push_back(i);
                    result.push_back(j);
                    return result;
                }
            }
        }
    }
};

这种方法时间复杂度是O(n2
)。

另一种方法是通过构建一个哈希表,以减少对数组中每一个数查找complement的时间,如下:

Your runtime beats 81.16 % of cpp submissions.
Runtime: 6 ms
#include <list>

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
    list<int> hashTable[10];
    int result_i, result_j;

    for (int i = 0; i < nums.size(); i++)
        hashTable[abs(nums[i] % 10)].insert(hashTable[abs(nums[i] % 10)].begin(), nums[i]);


    for (int i = 0; i < nums.size(); i++) {
        int key = abs((target - nums[i]) % 10);
        
        for (list<int>::iterator iter = hashTable[key].begin(); iter != hashTable[key].end(); iter++) {
            if (*iter + nums[i] == target) {
                result_i = i;

                for (int j = 0; j < nums.size(); j++) {
                    if (nums[result_i] + nums[j] == target && j != result_i) {
                        result_j = j;
                        vector<int> result;
                        result.push_back(result_i);
                        result.push_back(result_j);
                        return result;
                    }
                }   
            }
        }
    }
}
};
通过取模的哈希函数大大降低了查找的时间,但也增加了算法需要的空间。

看了solution之后,发现用了unordered_map,查阅文档后发现,其内部也是用哈希实现的:
Internally, the elements in the unordered_map are not sorted in any particular order with respect to either their key or mapped values, but organized into buckets depending on their hash values to allow for fast access to individual elements directly by their key values (with a constant average time complexity on average).
具体代码如下:

vector<int> twoSum(vector<int> &numbers, int target)
{
    //Key is the number and value is its index in the vector.
	unordered_map<int, int> hash;
	vector<int> result;
	for (int i = 0; i < numbers.size(); i++) {
		int numberToFind = target - numbers[i];

            //if numberToFind is found in map, return them
		if (hash.find(numberToFind) != hash.end()) {
                    //+1 because indices are NOT zero based
			result.push_back(hash[numberToFind] + 1);
			result.push_back(i + 1);			
			return result;
		}

            //number was not found. Put it in the map.
		hash[numbers[i]] = i;
	}
	return result;
}
这种算法在遍历数组将数组元素插入unordered_map的同时,也不断地在回顾已插入unordered_map中的元素是否包含当前要找的complement,最终只使用了一层循环就完成了,算法复杂度为O(n ​​ )。






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值