两数之和:哈希表高效解法,时间复杂度O(n)
<|begin▁of▁sentence|># 1. 两数之和
## 题目
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
## 示例
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]
## 提示
* 2 <= nums.length <= 104
* -109 <= nums[i] <= 109
* -109 <= target <= 109
* 只会存在一个有效答案
## 进阶
你可以想出一个时间复杂度小于 O(n2) 的算法吗?
## 解题思路
最直接的思路是暴力枚举,遍历数组中的每一个元素x,然后寻找数组中是否存在另一个元素y,使得x + y = target。但是这样的时间复杂度是O(n^2),空间复杂度是O(1)。
为了降低时间复杂度,我们可以使用哈希表。具体来说,我们可以创建一个哈希表,对于数组中的每一个元素x,我们首先查询哈希表中是否存在target - x,如果存在,那么我们就找到了对应的两个元素,返回它们的下标;如果不存在,那么我们就将x插入到哈希表中,这样在后续的遍历中,如果遇到target - x,就可以直接找到x。
这种方法的时间复杂度是O(n),因为哈希表的查找和插入操作的时间复杂度都是O(1)。空间复杂度是O(n),因为我们需要存储数组中的元素和它们的下标。
## 代码
```c
#include
#include
typedef struct {
int key;
int value;
int used;
} HashEntry;
typedef struct {
HashEntry *entries;
int size;
} HashTable;
HashTable* createHashTable(int size) {
HashTable *ht = (HashTable *)malloc(sizeof(HashTable));
ht->size = size;
ht->entries = (HashEntry *)calloc(size, sizeof(HashEntry));
for (int i = 0; i < size; i++) {
ht->entries[i].used = 0;
}
return ht;
}
void freeHashTable(HashTable *ht) {
free(ht->entries);
free(ht);
}
int hash(int key, int size) {
return abs(key) % size;
}
void insert(HashTable *ht, int key, int value) {
int index = hash(key, ht->size);
while (ht->entries[index].used) {
index = (index + 1) % ht->size;
}
ht->entries[index].key = key;
ht->entries[index].value = value;
ht->entries[index].used = 1;
}
int search(HashTable *ht, int key) {
int index = hash(key, ht->size);
while (ht->entries[index].used) {
if (ht->entries[index].key == key) {
return ht->entries[index].value;
}
index = (index + 1) % ht->size;
}
return -1;
}
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
HashTable *ht = createHashTable(numsSize * 2);
int *result = (int *)malloc(2 * sizeof(int));
*returnSize = 2;
for (int i = 0; i < numsSize; i++) {
int complement = target - nums[i];
int index = search(ht, complement);
if (index != -1) {
result[0] = index;
result[1] = i;
freeHashTable(ht);
return result;
}
insert(ht, nums[i], i);
}
freeHashTable(ht);
return result;
}
int main() {
int nums[] = {2, 7, 11, 15};
int target = 9;
int returnSize;
int *result = twoSum(nums, 4, target, &returnSize);
printf("[%d, %d]\n", result[0], result[1]);
free(result);
return 0;
}
```
## 复杂度分析
时间复杂度:O(n),其中n是数组中的元素数量。对于每一个元素x,我们可以O(1)地寻找target - x。
空间复杂度:O(n),其中n是数组中的元素数量。主要为哈希表的开销。
## 结果
执行结果:通过
执行用时:56 ms
内存消耗:7.1 MB
## 总结
通过使用哈希表,我们可以将时间复杂度从O(n^2)降低到O(n),虽然增加了空间复杂度,但在大多数情况下,这是一种值得的权衡。
最新文章
- 智能驾驶与电动汽车技术重塑未来出行生态
- 汽车无法启动原因排查
- 宝马驾驶体验如同驾驭未来科技
- 宝马全新M4雷霆版震撼上市
- 特斯拉自动驾驶技术引领未来出行
- 电动化与智能驾驶:动力电池与V2X技术引领汽车变革
- 固态电池突破:能量密度提升50%,充电速度翻3倍
- 智能驾驶技术突破:从L3到L4的五年变革之路
- 电动汽车三大技术突破:固态电池、无线充电与高效回收
- 激光雷达与车路协同:自动驾驶技术突破与未来五年趋势
- 智能传感器如何优化汽车悬挂系统的性能表现
- 动力电池与激光雷达引领新能源汽车智能化革命
- 车身结构优化:安全、轻量化与NVH性能的完美平衡
- 电动化浪潮:锂离子电池与高压平台驱动汽车产业变革
- 新能源汽车的“隐形大脑”:BMS如何守护电池安全?
- 智能网联与自动驾驶驱动新能源出行革命
- 汽车电磁兼容性设计:从线束布局到滤波技术的核心要点
- 固态电池技术突破:能量密度提升50%,超快充电重塑电动汽车未来
- 智能驾驶与电动化革命:未来出行的三大技术趋势
- 变速箱油革新与电池技术突破:智能养护新时代
