给定一个整数数组和一个目标值,数组找出状语从句:中目标值为的两个数。
你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
先写一个测试单元(要养成设计算法先写测试单元的习惯):
题目已经给出了一个测试用例,为了方便起见我直接运用了。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int nums[4] = { 2,7,11,15 };
int target = 9;
int* p = twoSum(nums, 4, target);
if (p != NULL)
{
printf("%d ",p[0]);
printf("%d \n", p[1]);
}
free(p);
p=NULL;
system("pause");
return 0;
}
由题目可以看出返回值为两个数组的下标所以返回一个指针,指针指向数组的两个下标。(函数的返回值只能是一个!)
可以看出我们要写一个函数函数需要有的参数为:。这个数组,数组的长度,目标值且函数的返回值是一个指针假如经过遍历整个数组,发现数组内没有满足和为目标值的元素,则返回空指针。
由于返回这个数组所以在函数执行完后,接收到返回的指针,且指针指向的内容为两个数组的下标。所以返回的值不能是在(局部变量)栈中创建。因为函数执行完后为在函数内的局部变量被销毁,所以在动态没存上开辟一块大小为2个整形的大小用来存放返回值,就避免在函数执行完后返回值被销毁了。(别忘了免费)
int* twoSum(int* nums, int numsSize, int target)
{
int* p=(int*)malloc(2 * sizeof(int));
.........//遍历数组寻找满足条件的两个数
return p;//返回p指针
.........
return NULL;//没有找到则返回NULL
}
下来我们来暴力的遍历数组吧
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int* twoSum(int* nums, int numsSize, int target)
{
assert(nums);
for (int i = 0; i<numsSize - 1; i++)//第一层循环从数组开头开始遍历nums[i] 开始i=0
{
for (int j = i + 1; j<numsSize; j++)//第二层循环nums[i+1]下一个元素
{
if (nums[i] + nums[j] == target)//满足题中给出条件即返回
{
int*p = (int*)malloc(2 * sizeof(int));
p[0] = i;
p[1] = j;
return p;
}
}
}
return NULL;
}
int main()
{
int nums[4] = { 2,7,11,15 };
int target = 9;
int* p = twoSum(nums, 4, target);
if (p != NULL)
{
printf("%d ",p[0]);
printf("%d \n", p[1]);
}
free(p);
p = NULL;
system("pause");
return 0;
}
复杂度分析:
-
时间复杂度:O(n ^ 2)O(n 2),对于每个元素,我们试图通过遍历数组的其余部分来寻找它所对应的目标元素,这将耗费O(n)O( n)的时间。因此时间复杂度为O(n ^ 2)O(n 2)。
-
空间复杂度:O(1)O(1)。
还有一种复杂低的算法,利用哈希表来解决这道题。由于本人还在学习当中,之后就会更新出来。