1.移除链表元素
给你一个链表的头节点
head
和一个整数val
,请你删除链表中所有满足Node.val == val
的节点,并返回 新的头节点 。
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val) {
struct ListNode* tail = head,*prev = NULL;
while(tail)
{
if(tail->val == val)
{
struct ListNode* tmp=tail->next;
if(prev !=NULL)//检查删除的是否为第一个元素
{
prev->next =tmp;
free(tail);
tail = tmp;
}
else{
free(tail);
tail = tmp;
head = tmp;
}
}
else
{
prev = tail;
tail = tail->next;
}
}
return head;
}
图解
删除val = 6的结点时,需要知道该结点的上一个结点,和下一个结点,所以在需要删除第一个元素时要特别注意,因为不能正常的找到它的上一个结点,同时当删除第一个结点后,链表的头节点要一起边(head = tail->next)
2.链表的中间结点
给你单链表的头结点
head
,请你找出并返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。
这道题是一道经典的快慢指针的题目,创建一个慢指针,一个快指针,我们发现当慢指针到达中间结点时,快指针已经走完了。所以可以设定慢指针一次走一步,快指针一次走两步。
当结点个数为奇数时我们可以发现当慢指针到达中间结点时,快指针fast->next == NULL
当结点个数为偶数时我们可以发现当慢指针到达中间结点时,快指针 fast == NULL
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* middleNode(struct ListNode* head) {
struct ListNode* show=head,*fast=head;
while(fast && fast->next)
{
show=show->next;
fast=fast->next->next;
}
return show;
}
3.输入一个链表,输出该链表中倒数第k个结点。
输入一个链表,输出该链表中倒数第k个结点。
这道题同样的也是一道经典的快慢指针的题目
我们可以让快指针先走k个结点后,慢指针再走,最后当快指针为空时,慢指针就走到了倒数第k个结点。
注意:输入的链表可能为空链表,这需要我们判断一下
代码
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
// write code here
struct ListNode* slow = pListHead, *fast = pListHead;
while(k--)
{
if(fast == NULL)//判断输入的是否为空链表
{
return NULL;
}
fast = fast ->next;
}
while(fast)
{
slow = slow ->next;
fast = fast ->next;
}
return slow;
}
希望以上题目能对大家有所帮助,让我们一起进步。