给你一个下标从 1 开始的整数数组 numbers
,该数组已按非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target
的两个数。如果设这两个数分别是 numbers[index1]
和 numbers[index2]
,则 1 <= index1 < index2 <= numbers.length
。
以长度为 2 的整数数组 [index1, index2]
的形式返回这两个整数的下标 index1
和index2
。
你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。
你所设计的解决方案必须只使用常量级的额外空间。(代码空间复杂度是O(1))
示例 1:
输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。
示例 2:
输入:numbers = [2,3,4], target = 6
输出:[1,3]
解释:2 与 4 之和等于目标数 6 。因此 index1 = 1, index2 = 3 。返回 [1, 3] 。
示例 3:
输入:numbers = [-1,0], target = -1
输出:[1,2]
解释:-1 与 0 之和等于目标数 -1 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 target
的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。
你可以按任意顺序返回答案。
法1:
-
时间复杂度:O(N2),其中 N 是数组中的元素数量。最坏情况下数组中任意两个数都要被匹配一次。
-
空间复杂度:O(1)。
cpp
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
int* returnArray;
int i, j;
returnArray = (int*)malloc(2*sizeof(int)); // 定义returnArray[2]
for (i = 0; i < numsSize-1; i++) {
for (j = i + 1; j < numsSize; j++) {
if ((nums[i] + nums[j]) == target) {
// printf("%d, %d\n", i, j);
returnArray[0] = i;
returnArray[1] = j;
*returnSize = 2;
return returnArray;
}
}
}
return returnArray;
}
法2:
时间复杂度:O(N),其中 N 是数组中的元素数量。对于每一个元素 x,我们可以 O(1) 地寻找 target - x。
空间复杂度:O(N),其中 N 是数组中的元素数量。主要为哈希表的开销。
cpp
#include "stdio.h"
#include "stdlib.h"
#include "uthash.h"
typedef struct {
int key;
int val;
UT_hash_handle hh;
} hashTable;
hashTable* hashtable;
hashTable* find(int ikey) {
hashTable* tmp;
HASH_FIND_INT(hashtable, &ikey, tmp);
return tmp;
}
void insert(int ikey, int ival) {
hashTable* it = find(ikey);
if (it == NULL) { // 没找到ikey对应的键值对,则向hashtable添加ikey对应的键值对
hashTable* tmp = (hashTable* )malloc(sizeof(hashTable));
tmp->key = ikey;
tmp->val = ival;
HASH_ADD_INT(hashtable, key, tmp);
}
else { // 找到了ikey对应的键值对,更新it
it->val = ival;
}
}
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
hashtable = NULL;
for (int i = 0; i < numsSize; i++) {
hashTable* it = find(target-nums[i]); // 哈希表中查找target-nums[i]的键值对
if (it != NULL) { // 找到了元素
int* ret = (int* )malloc(sizeof(int)*2);// 定义ret[2]
ret[0] = it->val; // target-nums[i]元素下标
ret[1] = i; // nums[i]元素下标
*returnSize = 2;
printf("%d %d\n", ret[0], ret[1]);
return ret;
}
insert(nums[i], i); // 哈希表中没找到target-nums[i]的键值对,则向哈希表中添加nums[i]的键值对,之后进行下一轮,直到找到对应的键值对
}
*returnSize = 0;
return NULL; // 输入有问题,没有对应输出
}
int main()
{
int* returnSize = (int* )malloc(sizeof(int)); // 必须用malloc初始化returnSize,否则twoSum报错写入访问权限冲突
int num[4] = {2, 7, 11, 15};
twoSum(num, 4, 9, returnSize);
return 0;
}