目录
一、移除链表元素
1、题目说明
2、题目解析
二、反转链表
1、题目说明
2、题目解析
三、链表的中间结点
1、题目说明
2、题目解析
一、移除链表元素
1、题目说明
题目链接:移除链表的元素
给你一个链表的头节点 head ,和一个整数 val,请你删除链表中所有满足Node.val == val 的节点,并返回新的头节点。
示例1:
输入:head = [1,2,6,3,4,5,6] , val = 6
输出:[1,2,3,4,5]
示例2:
输入:head = [ ] , val = 1
输出:[ ]
示例3:
输入:head = [7,7,7,7] , val =7
输出:[ ]
2、题目解析
思路:这种方法是重新在定义一个新的链表,它有新的头指针和尾指针,将不等于 val 的元素链接到这个个新的链表上,就相当于我们实现链表的尾插,我们只需要遍历一遍链表,然后将不等于val的链接到一起,等于 val 时就跳过,然后释放旧的链表,最后再返回新的链表即可。
注意:在这里是分两种情况:(1)如果链表为空时,则直接返回就行;(2)如果链表不为空时,并且当不等于val时,第一次尾插的时候直接将旧链表的cur复制过去,如果不是第一次,就可以在后面链接了,如果等于val时,就将其删除。
struct ListNode* removeElements(struct ListNode* head, int val)
{
struct ListNode* cur = head;
struct ListNode* newhead, * tail;
newhead = tail = NULL;
while (cur)
{
if (head == NULL)
return;
if (cur->val != val)
{
if (tail == NULL)
{
newhead = tail = cur;
}
else
{
tail->next = cur;
tail = tail->next;
}
cur = cur->next;
}
else
{
struct ListNode* newnext = cur->next;
free(cur);
cur = newnext;
}
}
//如果数组全部等于val时,就全部删掉,所以tail就为NULL了,所以要判断一下
if (tail)
tail->next = NULL;
return newhead;
}
二、反转链表
1、题目说明
题目链接:反转链表
给你单链表的头节点head,请你反转链表,并返回反转后的链表。
2、题目解析
思路1:从第一个元素开始头插,这个就完成了我们的反转。
struct ListNode* reverseList(struct ListNode* head)
{
struct ListNode* cur = head;
struct ListNode* rhead = NULL;
while (cur)
{
struct ListNode* next = cur->next;
//头插
cur->next = rhead;
rhead = cur;
cur = next;
}
return rhead;
}
思路2:直接反转链表的方向 。
struct ListNode* reverseList(struct ListNode* head)
{
if (head == NULL)
return NULL;
struct ListNode* n1, * n2, * n3;
n1 = NULL;
n2 = head;
n3 = n2->next;
while (n2)
{
n2->next = n1;//反转
n1 = n2;
n2 = n3;
if (n3)
n3 = n3->next;
}
return n1;
}
三、链表的中间结点
1、题目说明
题目链接:链表的中间结点
给定一个头节点为head的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。
2、题目解析
这道题有种比较巧妙的解法,就是用快慢指针,一个快指针fast,一个慢指针slow,快指针走两步,慢指针走一步。当fast->next为NULL时,slow刚好走到中间位置。
struct ListNode* middleNode(struct ListNode* head)
{
struct ListNode* slow, * fast;
slow = fast = head;
while (fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
本文要是有不足的地方,欢迎大家在下面评论,我会在第一时间更正。