[Algorithm][转载]两个指针(位置)的妙用

原文地址:http://blog.csdn.net/dlengong/article/details/7418420  作者:dlengong

使用两个指针可以轻松的解决许多算法问题,归纳出如下几种

1、  判断链表是否带环

带环链表的判断是链表中经常考察的内容。一个循环链表可以无休止地遍历下去。我们可以定义两个指针,一个快指针一个慢指针,如果在遍历到尾端前二者相遇,那么链表就是有环链表

2、  求链表中倒数第K个节点

如果用普通的思路得遍历两遍链表,第一遍先求出链表的总长度N,然后第二遍走到第N-k个节点,这个节点就是所求的节点。如果链表很长,那么遍历两次的话就很费时,我们用两个指针的方法遍历一次链表即可,先让一个指针走K步,然后两个指针再一起走,直到第一个指针遍历到链表末尾。

3、  二分法查找某个数

用经典的二分法在一个有序数组中可以以log(n)的时间复杂度查找出给定的数。同样也是设定两个位置下表,low与high。由于该方法大家都熟悉不过了,只把代码贴上来就行了

4、  在一个有序数组中找出和为N的两个数

定义两个位置low和high,一个在开始处,一个在结尾处,如果二者之和大于N,high递减,如果二者之和小于N则low递增,直到和为N或者二者相遇为止

5、  输入一个正数n,输出所有和为n连续正数序列

输入 15
输出
15=1+2+3+4+5
15=4+5+6
15=7+8

我们可用两个数low和high分别表示序列的最小值和最大值。首先把low初始化为1,high初始化为2。如果从low到high的序列的和大于n的话,我们向右移动low,相当于从序列中去掉较小的数字。如果从low到high的序列的和小于n的话,我们向右移动high,相当于向序列中添加high的下一个数字。一直到low等于(1+n)/2,因为序列至少要有两个数字

6、 输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分

如果不考虑时间复杂度,最简单的思路应该是从头扫描这个数组,每碰到一个偶数时,拿出这个数字,并把位于这个数字后面的所有数字往前挪动一位。挪完之后在数组的末尾有一个空位,这时把该偶数放入这个空位。由于碰到一个偶数,需要移动O(n)个数字,因此总的时间复杂度是O(n2)。

要求的是把奇数放在数组的前半部分,偶数放在数组的后半部分,因此所有的奇数应该位于偶数的前面。也就是说我们在扫描这个数组的时候,如果发现有偶数出现在奇数的前面,我们可以交换他们的顺序,交换之后就符合要求了。因此我们可以维护两个指针,第一个指针初始化为数组的第一个数字,它只向后移动;第二个指针初始化为数组的最后一个数字,它只向前移动。在两个指针相遇之前,第一个指针总是位于第二个指针的前面。如果第一个指针指向的数字是偶数而第二个指针指向的数字是奇数,我们就交换这两个数字

这道题有很多变种。这里要求是把奇数放在偶数的前面,如果把要求改成:把负数放在非负数的前面等,思路都是都一样的