数据结构 ——— 单链表oj题:移除链表中所有 val 的元素

目录

题目要求

手搓简易单链表

代码实现 


题目要求

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回新的头节点


手搓简易单链表

在实现以上逻辑函数前,要先手搓一个单链表出来,这样方便测试和调试

代码演示:

// 单链表中数据的类型
typedef int SLTDataType;

struct ListNode
{
	SLTDataType val; //单链表的数据

	struct ListNode* next; //指向下一个节点的指针
};

// 手搓单链表
int main()
{
	struct ListNode* n1 = (struct ListNode*)malloc(sizeof(struct ListNode));
	assert(n1);
	struct ListNode* n2 = (struct ListNode*)malloc(sizeof(struct ListNode));
	assert(n2);
	struct ListNode* n3 = (struct ListNode*)malloc(sizeof(struct ListNode));
	assert(n3);
	struct ListNode* n4 = (struct ListNode*)malloc(sizeof(struct ListNode));
	assert(n4);
	struct ListNode* n5 = (struct ListNode*)malloc(sizeof(struct ListNode));
	assert(n5);

	n1->val = 1;
	n2->val = 2;
	n3->val = 3;
	n4->val = 4;
	n5->val = 5;

	n1->next = n2;
	n2->next = n3;
	n3->next = n4;
	n4->next = n5;
	n5->next = NULL;

	return 0;
}

 在以后做单链表oj题时,都可以复用以上代码,对以上代码进行手动添加或删除节点,以便调试


代码实现

代码演示:

struct ListNode* removeElements(struct ListNode* head, int val)
{
	struct ListNode* cur = head;
	struct ListNode* prev = NULL;

	while (cur != NULL)
	{
		if (cur->val == val)
		{
			// 判断首节点的元素是否是 val
			if (prev == NULL)
			{
				cur = head->next;
				free(head);
				head = cur;
			}
			else
			{
				prev->next = cur->next;
				free(cur);
				cur = prev->next;
			}
		}
		else
		{
			prev = cur;
			cur = cur->next;
		}
	}

	return head;
}

代码解析:

cur 节点指针的作用是:找 val 元素

prev 节点指针的作用是:cur 节点的前一个节点,当 cur->val == val 时,prev->next 就能直接串联 cur->next

代码逻辑:以 cur 节点指针遍历整个链表,同时找 val 元素,找到了就利用 prev 节点指针改变指向,没有找到 cur 节点指针和 prev 节点指针就各自向后走一个节点
需要注意的是:当第一个节点的元素就是 val 时,需要判断处理,因为此时的 prev 还是 NULL ,以免对空指针解引用,所以当第一个节点的元素就是 val 时,就需要改变 head 头节点指针的指向,其他情况就 prev->next = cur->next 串联再释放 cur 节点即可

代码验证:

代码的时间复杂度:

while 循环执行了 N 次,且每次内部是 if 语句,也就是常数次,得出代码的时间复杂度:

时间复杂度(大O渐进表示法):O(N)

代码的空间复杂度:

没有开辟额外的空间,都是在 head 原链表中进行的删除,得出代码的空间复杂度:

代码的空间复杂度(大O渐进表示法):O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值