前言
笔者最近开始力扣刷题之旅,在这里记录我的学习过程,会不断的更新,刚开始会主要使用C,后面会不断更新,欢迎评论区讨论。
LeetCode-001-两数之和
题目描述
给定一个整数数组 nums 和一个整数目标值 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)
的算法吗?
题目待填函数 (C)
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
}
题目分析
题目要求
- 在给定数组nums中找出相加为target的两个数字
- 同一个数字不能重复
- 假设每一个target只对应一种答案
解题分析
#1-待填函数分析
int* twoSum(int* nums, int numsSize, int target, int* returnSize)
int* twoSum
代填函数 twoSum 为int* 类型函数,即返回值为int *,由题目要求分析得到twoSum返回的为一个数组,即一个数组。
int* num
指针变量nums指向nums数组,此形式等同于 int nums[]
int numsSize
nums数组中的元素个数
int target
需要求和的结果
int* returnSize
返回数组的长度 (对于像我这样的新手此处需要格外注意!!!)
#2-解题方法分析
法1:for循环遍历暴力求解
解决本题的关键在于找到两个相加为target的数。
一般我们在数组中查找一个数字,我们会想到使用for循环遍历数组进行查找。这里需要查找两个相加和为target的数字,我们可以使用两个嵌套的for循环以及两个循环变量来实现查找。
for(int i=0;i<numsSize;i++){
for(int j=i+1;j<numsSize;j++){
//判断相加是否等于target
if(nums[i]+nums[j]==target){
//把符合要求的下标放进数组
}
}
}
我们还需要建立一个数组用以存储符合要求的下标。(该数组我们命名为arr)
有两种方法建立arr数组
01-使用malloc函数创建arr数组
malloc函数说明
malloc函数的功能简单来说,就是在内存中开辟对应字节的空间,并返回该空间的第一个字节的地址。因此我们可以使用malloc函数分配空间后并将返回的地址赋给一个指针,并用该指针来访问这块分配出来的内存空间。
我们一般使用malloc()函数进行动态内存分配和变长数组
//因为char代表一个字节,所以传统上曾将malloc()定义为指向char的指针类型
下面是malloc()函数的代码格式
type *var_name = (type*)malloc(sizeof(type)*num);
在使用完malloc函数后
- 需要用free函数来释放malloc创建的内存空间
- 需要将创建的指针变量指向空指针,以防程序错误调用
free(pa);
pa = NULL;
-
如果申请后不释放,会内存泄露
-
如果无故释放,那就是什么也没有做
在本题的提示中已假设main函数中已有一个free函数来释放内存
所以这里不需要加上free函数
* Note: The returned array must be malloced, assume caller calls free().
创建样例
int *arr=(int*)malloc(2*sizeof(int));
方法01-完整代码示例
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
int *arr=(int*)malloc(2*sizeof(int));
for(int i=0;i<numsSize-1;i++){
for(int j=i+1;j<numsSize;j++){
if(nums[i]+nums[j]==target){
*returnSize=2;
arr[0]=i;
arr[1]=j;
return arr;
}
}
}
return NULL;
}
02-使用静态局部变量static创建arr[2]数组
对static的说明
一般情况下我们创建数组的方式为
int arr[2] = {0};
在函数中的变量叫做局部变量,在离开函数后,局部变量的内存空间将被释放,即如果我们按照上面的方法创建的arr数组空间在离开该函数后就被释放了,即使我们return了这个数组,它也不能被主函数接受
static的作用
- 修饰函数
- 修饰全局变量
- 修饰局部变量(这里使用第三个作用)
这里使用static的第三个作用,将局部变量数组arr,变成静态局部变量,即数组arr不会在出函数后销毁
创建样例
static int arr[2] = {0};//static修饰后,return的地址才能被main接受
方法02-完整代码示例
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
static int arr[2] = {0};//static修饰后,return的地址才能被main接收
for(int i=0;i<numsSize-1;i++){
for(int j=i+1;j<numsSize;j++){
if(nums[i]+nums[j]==target){
*returnSize=2;
arr[0]=i;
arr[1]=j;
return arr;
}
}
}
return NULL;
}
对于*returnSize的说明
一开始尝试这道题目时候*returnSize这个变量给我造成了极大的困惑
两个原因:
1. int* 这个让我一开始以为这是个数组,很可能是返回数组,但题目中没有说明,经过尝试后发现并不是。
2.在分析确定returnSize是指向一个int值的变量后,感觉很困惑,因为这个返回数组的大小只能是2不能是别的值,不懂它在这里的实际意义。
我在完成题目后对它的认识变为:
1.从完成题目的角度,我们不需要关心它的实际作用,并且在它的变量名已意义极其明确的情况下,即返回数组的长度,我们只需要按照题目要求完成相应的操作即可。
2.我觉得从一个完整的程序来说,我们可能需要在程序的各项环节中对我们的程序进程是否正确进行判断,在程序中我们会收到returnSize的变量输入,如果输出不是2则该步骤就存在问题,可能是用此。
欢迎在评论区进行讨论,指正。