【LeetCode刷题练习】(1.) 两数之和 Two Sum

两数之和 TWO SUM

题目:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

示例
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]


初解

int* twoSum(int* nums, int numsSize, int target, int* returnSize){
    int i=0,j=0;    
    while(nums[i]+nums[j]!=target){        
    	for(i=0;i<numsSize;i++){           
    		 for(j=i+1;j<numsSize;j++){               
    		 	 if(nums[i] + nums[j] == target){                    
    		 	 	printf("[%d,%d]",i,j);               
    		 	 	 }            
    		 	 }        
    		 }   
    	 }   
     return 0;
   }

运行结果
emmm不知道为什么出错,明明结果是对的一开始我没明白这个错误是为啥,按输出结果来说结果应该是正确的(去掉中括号以后也不对),具体错误信息如下(好像是说堆溢出?):

=================================================================
29ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000020 at pc 0x0000004019ab bp 0x7ffcb39f9e20 sp 0x7ffcb39f9e18
READ of size 4 at 0x602000000020 thread T0
#2 0x7fa483b9f2e0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202e0)
0x602000000020 is located 0 bytes to the right of 16-byte region [0x602000000010,0x602000000020)
allocated by thread T0 here:
#0 0x7fa48544e2b0 in malloc (/usr/local/lib64/libasan.so.5+0xe82b0)
#3 0x7fa483b9f2e0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202e0)
Shadow bytes around the buggy address:
0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa 00 00[fa]fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
29ABORTING

第一次修正代码

int* twoSum(int* nums, int numsSize, int target, int* returnSize){   
	 int i=0,j=0;       
	 for(i=0;i<numsSize;i++){            
	 	for(j=i+1;j<numsSize;j++){                
	 		if(nums[i] + nums[j] == target){                    
	 			printf("[%d,%d]",i,j);                
	 		}          
	 	  }       
	  }   
	 return 0;
}

第一次错误原因呢是多加了while语句导致堆栈溢出了,仔细一想好像确实也没必要,两个for循环就解决了,待我有时间需要查一查具体的原因。

再次运行,又出错了:

Line 207: Char 3: runtime error: load of null pointer of type ‘int’ (Serializer.c)

这次我明白了,因为题目要求函数返回类型为int*,而我的返回类型为整数int型,返回错误。

第二次修改代码

int* twoSum(int* nums, int numsSize, int target, int* returnSize){    
	int *a = (int *)malloc(sizeof(int) * 2);   
	int i, j;    
	for (i = 0; i < numsSize - 1; i++) {      
		for (j = i + 1; j < numsSize; j++) {           
			 if (nums[i] + nums[j] == target) {               
			 	a[0] = i;                
			 	a[1] = j;                
			 	*returnSize = 2;                
			 	return a;            
			 }        
		}    
	}                   
	*returnSize = 0;    
	return a;
}

顺利完成get√!


后记
现在是2020年1月13日,计划从现在开始每天认真练习做算法题,记住自己错误的地方,以后尽量少犯错,希望自己能坚持下来,无论以后是否会成为一个程序猿,都要努力提升自己。

每天一小步,日积月累就是一大步!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
给定一个整数数组 nums 和一个目标值 target,要求在数组中找出两个数的和等于目标值,并返回这两个数的索引。 思路1:暴力法 最简单的思路是使用两层循环遍历数组的所有组合,判断两个数的和是否等于目标值。如果等于目标值,则返回这两个数的索引。 此方法的时间复杂度为O(n^2),空间复杂度为O(1)。 思路2:哈希表 为了优化时间复杂度,可以使用哈希表来存储数组中的元素和对应的索引。遍历数组,对于每个元素nums[i],我们可以通过计算target - nums[i]的值,查找哈希表中是否存在这个差值。 如果存在,则说明找到了两个数的和等于目标值,返回它们的索引。如果不存在,将当前元素nums[i]和它的索引存入哈希表中。 此方法的时间复杂度为O(n),空间复杂度为O(n)。 思路3:双指针 如果数组已经排序,可以使用双指针的方法来求解。假设数组从小到大排序,定义左指针left指向数组的第一个元素,右指针right指向数组的最后一个元素。 如果当前两个指针指向的数的和等于目标值,则返回它们的索引。如果和小于目标值,则将左指针右移一位,使得和增大;如果和大于目标值,则将右指针左移一位,使得和减小。 继续移动指针,直到找到两个数的和等于目标值或者左指针超过了右指针。 此方法的时间复杂度为O(nlogn),空间复杂度为O(1)。 以上三种方法都可以解决问题,选择合适的方法取决于具体的应用场景和要求。如果数组规模较小并且不需要考虑额外的空间使用,则暴力法是最简单的方法。如果数组较大或者需要优化时间复杂度,则哈希表或双指针方法更合适。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值