leetcode题 两数之和 c语言暴力法 (错误集锦)+ 新人报道 请多多指点
两数之和
难度:简单
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
错误及解决方法
我的思路:两层循环,在nums数组中先循环找出一个小于target的元素nums[i],其次在nums数组中循环找出一个等于target-nums[i]的元素。
第一次代码如下:
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
int i,j,k;
for(i=0; i<numsSize; i++){
if(nums[i]<=target){
j=target-nums[i];
for(k=0; k<numsSize; k++){
if(j==nums[k]&&k!=i){
returnSize[0]=i;
returnSize[1]=k;
return returnSize;
}
}
}
}
returnSize[0]=0;
returnSize[1]=0;
return 0;
}
当然,这个代码执行错误,来看看错误提示
AddressSanitizer: stack-buffer-overflow on address 0x7fff0e9eb344 at pc 0x000000401ab2 bp 0x7fff0e9eb250 sp 0x7fff0e9eb240
那么这是什么意思呢?参考Address Sanitizer
stack buffer overflow 即栈缓存访问溢出,类似于以下代码:
int main (int argc, char** argv)
{
int array[100];
return array[100];//访问的位置超出栈上数组array的边界
}
首先来分析错误:1、函数参数中的int* returnSize明显不是表示结果的数组,而是结果数组的长度,这里根据题意直接赋值2就可以(由此报错栈缓存访问溢出)。2、由错误1而来,在这里需要自己为结果数组分配内存。
经过深思熟虑(百度找原因),第二次修改的代码如下:
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
int i,j,k;
*returnSize=2;
int * ret = malloc(sizeof(int) * 2);
for(i=0; i<numsSize; i++){
if(nums[i]<=target){
j=target-nums[i];
for(k=0; k<numsSize; k++){
if(j==nums[k]&&k!=i){
ret[0]=i;
ret[1]=k;
return ret;
}
}
}
}
return 0;
}
这次经过初步修改的代码执行成功了,测试样例输出正确,但当提交代码又出错了:执行错误,来看看错误提示
Line 207: Char 3: runtime error: load of null pointer of type 'int' (__Serializer__.c)
那么这个错误是什么,又出在代码的哪里呢?
Google翻译得出的结果是:第207行:Char 3:运行时错误:加载类型为“ int”的空指针(__Serializer __。c)。这里的Serializer应该指为数据定义序列化(不是很明白)
这个错误对我来说是这道题主要的拦路虎,经过很多次尝试,也用别人的代码通过了之后,我才发现原因,以下是成功的代码
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
int i,j,k;
*returnSize=2;
int * ret = malloc(sizeof(int) * 2);
for(i=0; i<numsSize; i++){
//if(nums[i]<=target){
j=target-nums[i];
for(k=0; k<numsSize; k++){
if(j==nums[k]&&k!=i){
ret[0]=i;
ret[1]=k;
return ret;
}
}
//}
}
return 0;
}
可以看出来与第二次错误的代码不同的是,我去掉了两层循环中间的一个判断,即出现错误的语句为注释掉的语句
结合错误提示,这条语句我一开始愣是没有看明白为什么错误,直到我看到了错误测试样例
[-1,-2,-3,-4,-5]
-8
当两数相加时,若存在一个数为负数,则其和target会小于其中的一个数,这是我从开始做题就存在的错误思维,没有考虑到负数相加的情况,从而导致改错艰难。
其他c语言方法解题:两遍哈希
新人报道 请多多指点
很惭愧,这是我在leetcode上做的第一道题,特意选的简单程度,做的情况并不是太好。
本科对于c、c++的学习仅限于通过考试水平,用我们老师的话说就是 只学到了一些基本语法,距离熟悉、掌握的阶段还很远,现在自己会利用平时的时间多学习编程知识,接下来的文章主要会用来记录自己学习的过程,做过的题,经历的笔试面试等等,希望大家都能在各自的领域越走越远。加油。
如果有错误欢迎指正,以后将不再重复(哈哈,我当然是尽可能分享(我认为)正确的)。