版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
题目要求
删除链表中等于给定值 val 的所有节点。
示例:
输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5
先决条件:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
解题思路
法一:给一个新的链表对原链表进行遍历,将非定值取出组成新链表
(该方法的空间复杂度为 n ,若题目要求为不允许新建链表,则不适用)
法二:(暴力求解)直接遍历链表,一个 newpoint 指针表示遍历到的位置、一个 lastpoint 指针指向遍历位置的上一个位置,将对应值的点删去即可,但是要考虑删除为头节点及尾节点的操作,步骤较为复杂,不推荐使用(详见下列代码块)
法三:给两个指针 cur 、res ,cur 遍历链表,res 进行查找,两个指针都指向第一个元素,res 向后移动找到非定值后传给 cur ,cur 完成对原链表值的覆盖向后移动,直到 res 指向空为止
解题演示
这里详细展示方法三:
输入为
- 1 3 4 4 5 4 6 , val = 4
输出为
- 1 3 5 6
过程:
- 指针指向第一个结点
- 为非指定元素,无需删除
- 遇到指定元素, cur 不传值给 res 且继续向后移动
- 同上,cur 指针继续向后移动
- 当 cur 指向为非指定元素时,传值给 res ,覆盖原有值
- 同上,重复查找覆盖工作
- 结束条件为,当 cur 指向 NULL 时,遍历完成,res 的 next 指向空,返回链表即可
实现代码
方法二:
struct ListNode* removeElements(struct ListNode* head, int val)
{
struct ListNode * newpoint, *lastpoint, *p;
//链表为空
if (head == NULL)
return head;
//删除头节点
while (head->val == val)
{
if (head->next != NULL)
head = head->next;
else
return NULL;
}
p = head;
//中间位置删除
if (head->next != NULL)
{
lastpoint = p;
p = p->next;
}
while (p->next != NULL)
{
if (p->val == val)
{
p = p->next;
lastpoint->next = p;
}
else
{
p = p->next;
lastpoint = lastpoint->next;
}
}
//尾节点删除
if (p->val == val)
{
lastpoint->next = NULL;
}
return head;
}
方法三:
struct ListNode* removeElements(struct ListNode* head, int val)
{
struct ListNode* cur, *res;
cur = res = head;
if (head == NULL)
return head;
else
{
while (head != NULL)
{
if (head->val != val)
{
res->val = head->val;
res = res->next;
}
head = head->next;
}
res = NULL;
return res;
}
}