1. 题目描述
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
2. 初解
遍历两层数组,一个一个加直到找出target
时间复杂度O(n^2)
int* twoSum(int* nums, int numsSize, int target) {
int* arr = NULL;
arr = (int* ) malloc(8);
int i = 0, j = 0;
for(; i < numsSize; i++) {
for(j=i+1; j < numsSize; j++) {
if(*(nums+i) + *(nums+j) == target) {
*arr = i;
*(arr+1) = j;
return arr;
}
}
}
return NULL;
}
3. 根据网上思路优化解法
用线性探测法的哈希表解决本题。
遍历一遍给定数组,当遍历到某个元素时,如果这个元素与某个已经加入到哈希表中的元素相加等于target,则直接返回下标,否则将该元素加入哈希表。
时间复杂度O(n)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define HTCAPACITY 50000
int hash(int key) {
int ret = key % HTCAPACITY;
return (ret < 0)?(ret + HTCAPACITY):(ret);
}
void htInsert(int *keys, int *values, int key, int value) {
int index = hash(key);
while(values[index] >= 0)
index = (index + 1) % HTCAPACITY;
keys[index] = key;
values[index] = value;
}
int htSearch(int *keys, int *values, int key) {
int index = hash(key);
while(values[index] >= 0) {
if(keys[index] == key)
return values[index];
index = (index + 1) % HTCAPACITY;
}
return -1;
}
// keys[index]和values[index]共同描述索引为index的哈希表项
// keys[index]表示该项的key
// values[index]为-1时表示该索引下无项
// values[index]为大于-1的整数时表示该项对应的key在题目给定数组nums[]中的下标
int* twoSum(int* nums, int numsSize, int target) {
int keys[HTCAPACITY] = {0};
int values[HTCAPACITY];
memset(values, -1, sizeof(int)*HTCAPACITY);
int *indices = (int *)malloc(sizeof(int)*2);
int value = -1, i = 0, complement;
for(i = 0; i<numsSize; i++) {
complement = target - nums[i];
if((value = htSearch(keys, values, complement)) != -1) {
indices[0] = value;
indices[1] = i;
return indices;
} else {
htInsert(keys, values, nums[i], i);
print(keys, values);
}
}
return NULL;
}
int main(int argc, char const *argv[])
{
int nums[] = {0, 1, 2, 0};
int *res = twoSum(nums, 4, 0);
printf("%d %d\n", res[0], res[1]);
return 0;
}
更新 C++ 版
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int, vector<int>::size_type> res;
for(unsigned i = 0; i < nums.size(); i++) {
int diff = target - nums[i];
if(res.find(diff) != res.end() && res[diff] != i) {
return {(int)res[diff], (int)i};
}
else {
res[nums[i]] = i;
}
}
return {};
}
};
4. 总结与思考
好久没写过c语言了,用Leetcode的第一道题开始c语言的学习之旅吧。
哈希表速度很快的原因是在理想情况下查找和插入的时间复杂度都是O(1),而这道题应用上哈希表后也没什么拐弯抹角的地方了。