常见单链表题型(一) 删除链表中等于给定值 val 的所有节点

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_44759710/article/details/101147765

题目要求

删除链表中等于给定值 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;
	}
}

猜你喜欢

转载自blog.csdn.net/qq_44759710/article/details/101147765