双指针算法详解——朋友跨年陪女友我陪算法

简介: 正片开始👀双指针👏首先咱得知道何为双指针,听起来很上流,其实有手就行。

正片开始👀

双指针👏

首先咱得知道何为双指针,听起来很上流,其实有手就行。


双指针,指的是在遍历对象的过程中,不是普通的使用单个指针进行访问,而是使用两个相同方向(快慢指针)或者相反方向(对撞指针)的指针进行扫描,从而达到相应的目的。


换言之,双指针法充分使用了数组有序这一特征,当遇到有序数组时,应该优先想到双指针来解决问题,因两个指针的同时遍历会减少空间复杂度和时间复杂度从而在某些情况下能够简化运算

image.png

对撞指针👏

类似于相遇问题,对撞指针是指在有序数组中,将指向最左侧的索引定义为左指针,最右侧的定义为右指针,然后分别从两侧出发,相向遍历链表,这个过程就形象化为对撞,习惯上就将左右指针定义为 left 和 right,我们给出一个大致代码逻辑:

void hit(int *arr,int arrsize)
{
int* left = arr;
int* right = arr + arrsize -1;
while(left<=right)
{
条件语句;
left++;
条件语句;
right--;
}
}

对撞指针适用于二分查找,链表对象求和等,也就是说当你遇到题目给定有序数组时,应该第一时间想到的思路就是使用对撞指针。


快慢指针👏

类似于龟兔赛跑,快慢指针是两个链表上的指针从同一节点出发,其中一个指针前进速度比另一个快,两个指针以不同的策略移动,直到两个指针的值达成某个条件为止,如图(ppt绘图+手残勿喷):

image.png

我们同样将左右指针定义为 slow,fast,要实现其中一个指针比另一个快,我们无可厚非就两种方法:

1.同时起步,fast 比 slow 多走n步;

2.fast 先走,slow后走;

那我们给出他的逻辑代码:

同时走:

void speed(int *arr)
{
   int* fast = arr;
   int* slow = arr;
   while(slow<fast)
   {
   条件;
   slow++(非条件下fast++);
   }
}
void speed(int *arr)
{
int* slow =arr;
int* fast = arr;
while(条件1)
{
slow++;
}
while(条件2)
{
fast++;
}
}

真题实战👏

1.调整数组顺序使奇数位于偶数前面

牛客真题链接

int* reOrderArray(int* array, int arrayLen, int* returnSize ) {
  *returnSize = arrayLen;
   int* left = array;
  int* right = array + arrayLen - 1;
  while (left < right)//(1)
  {
    while (left < right && *left % 2 == 1)//(2)
      left++;
    while (left < right && *right % 2 == 0)//(3)
      right--;
    if (left < right)//(4)
    {
      int tmp = *left;
      *left = *right;
      *right = tmp;
    }
    left++;
    right--;
  }
  return array;
}

这道题就是典型的对撞指针,我们遍历完整个数组时,左右指针路程各自一半,只需要 left 寻找奇数,right 寻找偶数做交换即可。

==Ps.==这里的* returnSize

2.Leetcode 真题:移除元素

int removeElement(int* nums, int numsSize, int val) {
  int* p1 = nums;
  int* p2 = nums;
  int sz = numsSize;
  for (; p1 < nums + numsSize; p1++)
  {
    if (*p1 != val)
    {
      *p2 = *p1;
      *p2++;
    }
    else
      sz--;
  }
  return sz;
}  

这是典型的快慢指针,第一个指针用来遍历数组元素,判断是不是要删除的数,第二个指针用来存放数字。如果第一个指针指向的是要删除的元素,那么输出用来存放输出数组元素个数的整形变量sz就自减 1,然后第一个指针向后移动一位,第二个指针不动;如果第一个指针指向的不是要删除的数,那么就把这个数放到第二个指针指向的位置,然后第一个指针和第二个指针都向后移动一位。重复操作直到第一个指针遍历整个数组,此方法的时间复杂度是O(n)。

相关文章
|
5天前
|
算法 前端开发 JavaScript
< 每日算法:一文带你认识 “ 双指针算法 ” >
`双指针`并非指的是一种具体的公式或者范式。而是一种运算思路,用于节省逻辑运算时间的`逻辑思路`!双指针算法通常用于`优化时间复杂度`!
< 每日算法:一文带你认识 “ 双指针算法 ” >
|
15天前
|
算法
优选算法|【双指针】|202.快乐数
优选算法|【双指针】|202.快乐数
|
16天前
|
算法
【优选算法专栏】专题一:双指针--------1.移动0
【优选算法专栏】专题一:双指针--------1.移动0
19 0
|
30天前
|
算法 关系型数据库 MySQL
大厂算法指南:优选算法 ——双指针篇(下)
大厂算法指南:优选算法 ——双指针篇(下)
26 0
|
1月前
|
算法 容器
算法思想总结:双指针算法
算法思想总结:双指针算法
|
1月前
|
存储 算法 容器
【优选算法】—— 双指针问题
【优选算法】—— 双指针问题
【优选算法】—— 双指针问题
|
1月前
|
算法
我对双指针算法认知
我对双指针算法认知
|
2月前
|
算法 测试技术 C++
【双指针】【C++算法】1537. 最大得分
【双指针】【C++算法】1537. 最大得分
|
1月前
|
传感器 算法 计算机视觉
基于肤色模型和中值滤波的手部检测算法FPGA实现,包括tb测试文件和MATLAB辅助验证
该内容是关于一个基于肤色模型和中值滤波的手部检测算法的描述,包括算法的运行效果图和所使用的软件版本(matlab2022a, vivado2019.2)。算法分为肤色分割和中值滤波两步,其中肤色模型在YCbCr色彩空间定义,中值滤波用于去除噪声。提供了一段核心程序代码,用于处理图像数据并在FPGA上实现。最终,检测结果输出到&quot;hand.txt&quot;文件。