本文已参与「新人创作礼」活动,一起开启掘金创作之路
前言
本系列主要讲解链表的经典题
注:划重点!!必考~
找到链表的中间结点
- 题目描述:
给定一个头结点为
head的非空单链表,返回链表的中间结点如果有两个中间结点,则返回第二个中间结点
- 示例:
编辑
- 提示:
- 给定链表的结点数介于
1和100之间
- 解题思路:
- 一般的思路:
一个个遍历,得到链表长度,在遍历链表长度的二分之一,就能得到中间结点
高效思路:
- 使用两个指针
- 一个慢指针每次走一个结点的位置
- 一个快指针每次走慢指针的两倍长度
- 当快指针走完链表时,而慢指针则恰在链表中间结点位置
注意:链表长度有奇数和偶数两种情况
注:这里我们来实现高效思路
- 图示:
编辑
- 参考代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* middleNode(struct ListNode* head){
//创建快慢指针,快指针走两步,而慢指针走一步(当快指针到尾时,慢指针在中间)
struct ListNode*slow,*fast;
slow=fast=head;
//节点为单数时,快指针走到尾节点(fast下一个节点为NULL则停止)
//节点为双数时,快指针走到尾节点的下一个节点NULL(fast为NULL则停止)
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
- 结果:
链表中倒数第k个结点
- 题目描述:
输入一个链表,输出该链表中倒数第k个结点
- 示例:
- 解题思路:
- 一般思路:
遍历链表两次
高效思路:
- 使用两个指针
- 快指针先走k步
- 慢指针再与快指针一起走
- 当快指针走完时,慢指针走到倒数第k个结点
注意:k的大小可能超过链表长度这一特殊情况
注:这里我们来实现高效思路
- 参考代码:
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
/**
*
* @param pListHead ListNode类
* @param k int整型
* @return ListNode类
*/
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
//链表不为NULL
if(pListHead==NULL)
return NULL;
struct ListNode* slow=pListHead,*fast=pListHead;
while(k--)
{
//节点数量比k小
if(fast==NULL)
return NULL;
fast=fast->next;
}
//fast为NULL则停止
while(fast)
{
fast=fast->next;
slow=slow->next;
}
return slow;
}
- 结果: