【牛客网刷题篇】链表 -- 快慢指针的应用

一 . 链表中倒数第k个结点

1. 题目描述

假设给定某个链表, 让你输出链表中倒数第k个结点

2. 题解

思路一 – 快慢指针的应用方式

思路 : 让指针一比指针二快k个结点, 如此当指针一走到链表尾部时, 指针二恰好走到链表倒数第k+1个结点, 当指针一指向空时, 指针二恰好指向链表倒数第k个结点

class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) 
	{
		ListNode* fast = pListHead;
		ListNode* slow = pListHead;
		int num = k;
		int count = 0;
		while(k--)
		{
			if(!fast)
			{
				break;
			}
			fast = fast->next;
			count++;
		}
		if(num>count)
		{
			return NULL;
		}
		while(fast)
		{
			fast = fast->next;
			slow = slow->next;
		}
		return slow;
    }
};

作者 : Joker不是Joker
时间复杂度 : O(n)  // 最差运行 n次
空间复杂度 : O(1)

评价 : 此题 快慢指针应用思路简单 , 但是数组越界情况较多, 或者说实际中特殊情况较恶心, 导致代码需要多次使用if语句进行判断。

思路二 – 单指针二次遍历

class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) 
	{
		ListNode* cur=pListHead;
		int count = 0;
		while(cur)
		{
			cur = cur->next;
			++count;
		}
		cur = pListHead;
		count=count-k+1;
		int num = 1;
		while(cur)
		{
			if(num == count)
			{
				break;
			}
			cur = cur->next;
			++num;
		}
		return cur;
    }
};
作者 : Joker不是Joker
时间复杂度 : O(n)  // 最差运行 2n次
空间复杂度 : O(1)

二 . 链表分割

1. 题目描述

现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针

2. 题解

思路一 双指针的应用

两个指针一前一后, 指针一指向指针二前一个结点, 每次循环判断指针二指向的结点的数值域是否小于x , 如果小于x将其头插入该链表中, 指针一用于记录指针二指向的节点

三. 链表的回文结构

1.题目描述

对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。

2. 题解

思路一 – 快慢指针的应用

先让一个指针遍历一次该链表, 然后统计链表中节点的个数。 记为count
如果节点个数为奇数 , 返回false
如果节点为偶数 , 让两个指针都指向链表中的第一个节点 ,
然后更新 fast指针, 让其先走count/2个节点
此时进行while循环,每次循环判断fast 与slow指向的节点的指针域是否相同 ,如果不同返回 false
如果循环正常结束, 代表该链表是回文结构, 返回true 。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值