【双指针】早早开启双指针的大门

简介: 【双指针】早早开启双指针的大门
同向双指针 移动速度相同,一般同向移动
双向双指针 移动速度相同,一般相向移动
快慢双指针 移动速度不同

问题1:同向双指针:

ac23ab46c432408e8c58beb15790b2f0.png

【力扣】1. 两数之和

ba4c6dfe8c2d44be850f7a0c0d5dc044.png


解题;


使用同向双指针,两个指针首先都指向第一个元素,然后先固定第一个指针,第二个指针向后遍历,判断两个指针指向的数组元素之和是否等于给定的目标和值,如果不等,等第二个指针遍历完后,第一个指针再向后移动一位,第二个指针再从第一个指针的位置向后遍历整个数组,以此类推。(有点像选择排序的过程)


时间复杂度:n+(n-1)+....+1=n*(n-1)/2


也就是o(n^2)


代码:(注意:代码并不一定能在力扣上跑)

int main()
{
  int a[5] = { 1,2,3,4,5 };
  int sz = sizeof(a) / sizeof(a[0]);
  int key = 9;
  for (int i = 0; i < sz - 1; i++)
  {
    for (int j = i;j < sz; j++)
    {
      if (a[i] + a[j] == key)
      {
        printf("在数组中%d和%d的和为%d\n",a[i],a[j],key);
      }
    }
  }
  return 0;
}

对于同向指针:如果我要你删除链表倒数第n个结点(未知链表长度情况下,如果常规遍历要要先确定链表长度,然后做减法知道倒数第n个结点所在的正序位置,从而遍历到该位置),但是如果我们使用同向指针(只用遍历一遍,时间复杂度n,高效!)


5af644182faa4f908ade5990f3e4336d.png


解决办法:让指针1先遍历到第n个结点,然后指针2指向首元结点,然后两个指针以同样的速度向右移动,当指针1遇到尾结点停下来的时候,指针2也就自然地到了倒数第n个结点的位置。


问题2:双向双指针:(还是两数之和那题)


005297763b94449da97e8a8cc313f70f.png


解题:


注意到该数组原本有序,因此要小心,再思考一下下


我们可以使第一个指针指向第一个元素(左指针),第二个指针指向最后一个元素(右指针),将指针指向的元素相加和目标和值比较,由于数组是有序的:


如果两指针指向的数组元素相加之和大于目标和值,就使右指针回退一位,左指针不动;


如果两指针指向的数组元素相加之和小于目标和值,就使左指针回退一位,右指针不动;


如果两指针指向的数组元素相加之和等于目标和值,就得到结果。


时间复杂度:o(n)


代码:

int main()
{
  int a[5] = { 1,2,3,4,5 };
  int sz = sizeof(a) / sizeof(a[0]);
  int key = 7;
  int left = 0, right = sz - 1;
  while (left<right)
  {
    if (a[left] + a[right] > key)  right--;
    else if (a[left] + a[right] > key)  left++;
    else
    {
      printf("在数组中%d和%d的和为%d\n", a[left], a[right], key);
      break;
    }
  }
  return 0;
}

问题3:快慢双指针:

3c8c5415379d4ca4b2e306693c5bf102.png



题目链接传送门【力扣】141. 环形链表


b4c2939b97c34962992524c6ce8210c5.png


17dfbb4a361d4f9b802c0b0d4c1a0c4f.png


解题:


我们设置两个指针,一个快指针,一个慢指针,当慢指针走一步,快指针就走两步


如果链表没有环,那么快指针因为走的快,就会在链表的最后一个结点或者倒数第二个结点处停下来


如果链表有环,那么就会快指针因虽然走的快,但是因为有环,快指针和慢指针肯定会在环的某点(其实就是环的入口点)相遇


代码:

bool hasCycle(struct ListNode *head) {
    struct ListNode* slow=head;
    struct ListNode* fast=head;
    while(fast->next!=NULL&&fast->next->next!=NULL)
    {
        fast=fast->next->next;
        slow=slow->next;
        if(slow==fast)
        {
            return ture;
        }
    }
    return false;
}
目录
相关文章
|
6月前
|
算法
LeetCode刷题---19. 删除链表的倒数第 N 个结点(双指针-快慢指针)
LeetCode刷题---19. 删除链表的倒数第 N 个结点(双指针-快慢指针)
|
6月前
|
存储 容器
LeetCode刷题---11. 盛最多水的容器(双指针-对撞指针)
LeetCode刷题---11. 盛最多水的容器(双指针-对撞指针)
|
6月前
|
算法
LeetCode刷题---167. 两数之和 II - 输入有序数组(双指针-对撞指针)
LeetCode刷题---167. 两数之和 II - 输入有序数组(双指针-对撞指针)
|
6月前
|
算法
LeetCode刷题---160. 相交链表(双指针-对撞指针)
LeetCode刷题---160. 相交链表(双指针-对撞指针)
|
6月前
|
算法 索引
LeetCode刷题---142. 环形链表 II(双指针-快慢指针)
LeetCode刷题---142. 环形链表 II(双指针-快慢指针)
|
6月前
|
算法 索引
LeetCode刷题---141. 环形链表(双指针-快慢指针)
LeetCode刷题---141. 环形链表(双指针-快慢指针)
|
11月前
|
C语言
【LeetCode】——双指针(快慢指针)/多指针
大家好!这是新开的LeetCode刷题专栏,这个专栏不只是随便的拿一些我练过的题讲解,而是总结我在刷题中的一些方法适用于一大类的题,是给大家提供这一大类题的解题方法或者思路,希望能给一些刚开始刷题的小白提供帮助,防止他们在刚开始刷题时,由于LeetCode的难度而从入门到入土,从而放弃,刚开始也是使用最基础的C语言来讲解。
|
11月前
|
存储
双指针与逆向双指针的妙用
双指针与逆向双指针的妙用
力扣82删除排序链表中的重复元素 II:思路分析+代码实现+方法总结(三指针法&快慢指针法【双指针】&递归法)
力扣82删除排序链表中的重复元素 II:思路分析+代码实现+方法总结(三指针法&快慢指针法【双指针】&递归法)
71 0
|
存储 算法 安全
LeetCode算法小抄 -- 链表(快慢指针、双指针、回文链表)
LeetCode算法小抄 -- 链表(快慢指针、双指针、回文链表)