双指针法

1、基本概念

双指针主要分为以下三种:

普通的指针:两个指针往一个方向移动
对撞指针:一般是在有序的情况下两个指针进行面对面的移动,适合解决约束条件的一组元素问题以及字符串反转问题
快慢指针:定义两个指针,一个快指针一个慢指针,用于判断是否为环或者长度的问题很方便

通过一个快指针和慢指针在一个for循环下完成两个for循环的工作,把输出的数组直接写在输入数组上。

右指针 fast 指向当前将要处理的元素,左指针 slow 指向下一个将要赋值的位置。

如果 fast 指针指向的元素不等于 val,它一定是输出数组的一个元素,我们就将 fast 指针指向的元素复制到 slow 指针位置,然后将两个指针同时右移;

如果右指针指向的元素等于 val,它不能在输出数组里,此时 slow 指针不动,fast 指针右移一位。

整个过程保持不变的性质是:区间 [0,slow) 中的元素都不等于val。当左右指针遍历完输入数组以后,slow 的值就是输出数组的长度。

2、代码实现

 1 class Solution {
 2 public:
 3     int removeElement(vector<int>& nums, int val) {
 4         // 双指针
 5         int slow = 0;
 6         int n = nums.size();
 7         for (int fast = 0; fast < n; fast++){
 8             if (nums[fast] != val){
 9                 nums[slow] = nums[fast];
10                 slow++;
11             }
12         }
13         return slow;
14     }
15 };

3、降低时间复杂度

假设我们有一个二维数组arr,大小为n x m,我们要对其进行双层循环遍历,原代码如下:

1 for (int i = 0; i < n; i++) {
2     for (int j = 0; j < m; j++) {
3         // 执行操作
4     }
5 }

我们使用双指针优化这个循环。首先,我们定义两个指针p1和p2,初始时分别指向数组的第一个元素。然后,我们使用一个循环来遍历数组,每次迭代更新指针的位置,并执行操作

 1 int p1 = 0; // 第一个指针初始位置
 2 int p2 = 0; // 第二个指针初始位置
 3 
 4 while (p1 < n && p2 < m) {
 5     // 执行操作
 6 
 7     // 更新指针的位置
 8     p2++;
 9     if (p2 == m) {
10         p2 = 0;
11         p1++;
12     }
13 }

4、例题

给定一个有序的递增数组,数组arr={1,3,4,9,11,12,14},找到两个数之和为12,找到一组即可停止
思路:这题最容易想到的就是暴力算法,即直接两层循环嵌套逐个查找,但时间复杂度为:O(n^2)
暴力算法:

1 for(int i=0;i<n;i++){
2     for(int j=0;j<n;j++){
3     if(arr[i]+arr[j]==k)
4     cout<<arr[i]<<arr[j]>>endl;
5     }
6 }

双指针:这题使用双指针大大降低了时间复杂度

 1     int i = 0; // 从头开始的索引
 2     int j = arr.size() - 1; // 从尾开始的索引
 3     
 4 while (i < j)
 5 {
 6     if (arr[i] + arr[j] < k)
 7     {
 8         i++; // 如果arr[i]和arr[j]的和小于k,则增加i的值
 9     }
10     else if (arr[i] + arr[j] > k)
11     {
12         j--; // 如果arr[i]和arr[j]的和大于k,则减小j的值
13     }
14     else
15     {
16         cout << arr[i] << arr[j] << endl; // 如果arr[i]和arr[j]的和等于k,则输出这两个数并结束循环
17         break;
18     }
19 }
20 
21 return 0;

 

posted @ 2024-04-02 08:53  taohuaxiaochunfeng  阅读(24)  评论(0编辑  收藏  举报