Two Sum(初谈双指针)
2016-04-10 12:59
405 查看
昨天晚上遇到这么一个题目,然后听到了关于“双指针”的使用。好了,言归正传,先来看一看这个题目:
但是,在通过第一组测试数据之后,出现了新的问题:
但是由于在前面经过了排序,数组元素的下标已经改变,所以,最后的输出结果变成了[0, 2]。
于是,不得不采用最原始的解决办法,嵌套循环全部遍历,虽然大大增加了运算时间,但是总算解决了问题,当然,代码实现也就更简单了,具体代码如下:
这里还有一个细节的问题,就是这个:int *Result = (int)malloc(sizeof(int)* 2);
一开始的时候,返回的这个数组我是直接定义的:int Result[2];
但是发现返回后在主函数内打印是不可行的,虽然后来改为了动态分配解决了这个问题,但是并不知道原因所在,现在了解到:
函数内开辟的这个数组空间,是存在于栈当中的,函数在完成功能后,当时使用的内存空间是拒绝再被访问的,你返回的那个数组的首地址—Result,也是毫无意义,然后动态分配的空间是存在于堆当中的,是一个共享的空间,大家都可以使用,所以,即使函数完成了功能,也是可以被主函数访问的。
关于堆和栈的更多详细的内容,我借鉴前辈的经验,也写了一点,有兴趣的可以到这里去看看关于堆和栈(直接点我)
首先对该无序数组进行排序,随后用两个变量指向数组的开头和结尾:这里我们使用low和high,分别指向nums[0]和nums[numsSize];因为已经进行过排序,如果nums[low]+nums[high] < target,则说明low指向的数太小,需要往后移动;反之,则是high指向的数太大,需要前移,当两者相等,遍历结束 。
完全代码如下:
修改了好一阵子,终于给了AC,当然收获也是良多的,这道题也有哈希的做法,现在还不是很懂,在后面的学习中会慢慢补上这一部分,也会谈一下对栈、堆的理解。新手上路,错误之处,还望指正!
Given an array of integers, return indices of the two numbers such that they add up to a specific target. |
---|
You may assume that each input would have exactly one solution |
Example: |
---|
Given nums = [2, 7, 11, 15], target = 9, |
Because |
nums[0] + nums[1] = 2 + 7 = 9, return [0, 1]. |
1. 嵌套循环解法
首先说一下我自己在面向这个题的时候的解法:首先,我认为对该无序数组进行排序,目的是为了减少遍历时间。以题目给的数据为例:sort(nums, nums + numsSize); int *Result = (int*)malloc(sizeof(int)* 2); for (int i = 0; i < numsSize - 1; i++){ for (int j = i + 1; j < numsSize; j++){ if (nums[i] + nums[j] == target){ //写入 Result[0] = nums[i]; Result[1] = nums[j]; } if (nums[i] + nums[j] > target) //跳出判断 break; } } return Result;
但是,在通过第一组测试数据之后,出现了新的问题:
Example: |
---|
Given nums = [3, 2, 4], target = 6, |
Because |
nums[1] + nums[2] = 2 + 4 = 6, return [1, 2]. |
于是,不得不采用最原始的解决办法,嵌套循环全部遍历,虽然大大增加了运算时间,但是总算解决了问题,当然,代码实现也就更简单了,具体代码如下:
int *Result = (int*)malloc(sizeof(int)* 2); for (int i = 0; i < numsSize - 1; i++){ for (int j = i + 1; j < numsSize; j++){ if (nums[i] + nums[j] == target){ Result[0] = i; Result[1] = j; } } } return Result;
这里还有一个细节的问题,就是这个:int *Result = (int)malloc(sizeof(int)* 2);
一开始的时候,返回的这个数组我是直接定义的:int Result[2];
但是发现返回后在主函数内打印是不可行的,虽然后来改为了动态分配解决了这个问题,但是并不知道原因所在,现在了解到:
函数内开辟的这个数组空间,是存在于栈当中的,函数在完成功能后,当时使用的内存空间是拒绝再被访问的,你返回的那个数组的首地址—Result,也是毫无意义,然后动态分配的空间是存在于堆当中的,是一个共享的空间,大家都可以使用,所以,即使函数完成了功能,也是可以被主函数访问的。
关于堆和栈的更多详细的内容,我借鉴前辈的经验,也写了一点,有兴趣的可以到这里去看看关于堆和栈(直接点我)
2.双指针解法
双指针解法的优化之处在于仅需要一次遍历就可以达到目的。好,直接进入主题:首先对该无序数组进行排序,随后用两个变量指向数组的开头和结尾:这里我们使用low和high,分别指向nums[0]和nums[numsSize];因为已经进行过排序,如果nums[low]+nums[high] < target,则说明low指向的数太小,需要往后移动;反之,则是high指向的数太大,需要前移,当两者相等,遍历结束 。
完全代码如下:
int compi(const void *a, const void *b){ //C的qsort要用的函数 return (*(int*)a - *(int*)b); } int* twoSum(int* nums, int numsSize, int target){ bool flag = true; int* Result = (int*)malloc(sizeof(int)* 2); int* temp = (int*)malloc(sizeof(int)*numsSize); //复制数组来找真正的下标 for (int i = 0; i < numsSize; i++) temp[i] = nums[i]; qsort(nums, numsSize,sizeof(nums[0]),compi); int low = 0; int high = numsSize - 1; while (low < high){ if (nums[low] + nums[high] < target) low++; else if (nums[low] + nums[high] > target) high--; else break; } //flag用于解决nums[low]和nums[high]相等造成无法给Result[1]赋值的情况 for (int i = 0; i < numsSize; i++){ if (temp[i] == nums[low] && flag==true) { Result[0] = i; flag = false; } if (temp[i] == nums[high]) { Result[1] = i; } } //如果返回数组的数值大小不正确,交换 if (Result[0] > Result[1]){ int temp = Result[0]; Result[0] = Result[1]; Result[1] = temp; } return Result; }
修改了好一阵子,终于给了AC,当然收获也是良多的,这道题也有哈希的做法,现在还不是很懂,在后面的学习中会慢慢补上这一部分,也会谈一下对栈、堆的理解。新手上路,错误之处,还望指正!
相关文章推荐
- nmon结果分析
- android中对输入手机号码有效性验证(是否为正确的手机号码)
- 将非Maven管理的jar打包到Maven本地资源库
- Maven3 --- Eclipse集成Maven
- 组合数
- Sharepoint 构建轻量型应用之传出电子邮件设置!
- Linux内核分析——可执行程序的装载
- android入门之使用adb shell 查看data目录下的SQLite数据库
- ConcurrentModificationException异常
- Android权限
- WaitForMultipleObjects使用详解
- 3最短路的几种解法 ------例题< 最短路 >
- Unity UGUI图文混排源码(二)
- 表示数值的字符串
- Unity UGUI图文混排源码(二)
- IOS开发 随笔
- 【机房重构】导出Excel
- DML、DDL、DCL区别
- neutron agent-list 没有任何输出 AMQP server on controller:5672 is unreachable:
- Unity UGUI图文混排源码(一)