首先,什么是双指针:
首先我们要明确一个概念,这里所说的指针,并不是cpp中的对内存地址进行操作的指针变量,他的性质更类似于数组的下标索引,通过两个索引来实现一些需要的功能,而对双指针进行细分,大致可以分成以下两种:(1)快慢指针;(2)左右指针;
这里我们先对快慢指针进行介绍。
------------------------------------什么是快慢指针---------------------------------------------
顾名思义,快慢指针的意思是两个移动速度不一样的指针,首先我们来看一道leetcode 的题目(难度:简单):
此时我们直接思考双指针的解法,设置指针i,每次向前移动两步(防止链表节点为双数,每次移动必须检查后面的节点是否为null),指针j每次向前移动一步,如果指针i和指针j可以重合,那链表就是一个环形链表,这就是使用双指针的方式对链表是否为环形进行判断。此题我暂时没有进行代码的实现,所以在这里不列出代码了。
下面再看另一个类似的例子(难度:简单):
同样的思考方式:一个指针i用于遍历数组,另一个指针j用于对数组中的元素进行更新,每次当i遍历到nums[i] = val的时候,便不对i指向的元素进行更新,这样在一趟遍历下,i遍历过的区域,就可以在不改变数组排列的情况下,将其余元素顺序不变地载入。
代码如下所示:
class Solution { public: int removeElement(vector<int>& nums, int val) { if(nums.size() == 0) return 0; int res = 0; //设置返回值 for(int i = 0;i < nums.size();i++) { if(nums[i] == val) continue; nums[res] = nums[i]; res++; } return res; } };
--------------------------------------左右指针-------------------------------------------
同样地,这里给出一个算法题(难度:中等):
这里便是两个指针,一个从最左边开始,一个从最右边开始,然后逐步移动指针(移动的方法,大家可以自己思考一下),然后通过对容器体积的更新,实现筛选出最大容器其的目的,这就是一个典型左右指针 的方案。
补充:
除了上述介绍的快慢指针和左右指针外,双指针有一个称为“滚动条法”的使用方法,大家有兴趣的可以了解一下,但是我个人认为滚动条法和快慢指针的方法,是有相似之处的。