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

同向双指针移动速度相同,一般同向移动
双向双指针移动速度相同,一般相向移动
快慢双指针移动速度不同

问题1:同向双指针:

【力扣】1. 两数之和

 解题;

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

时间复杂度: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,高效!)

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

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

解题:

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

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

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

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

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

时间复杂度: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:快慢双指针:

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

解题:

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

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

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

代码:

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;
}
  • 16
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码上心头

为爱发电

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值