C语言进阶|链表经典OJ题

✈移除链表元素

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

方法一:

遍历链表找到所有等于val的节点,再执行删除操作删除这些节点。

方法二:

双指针

创建两个指针,一个在前,一个在后。

如果前面的指针指向的元素等于val,将后面的指针连上前面指针的下一个指针,前面的指针向前走一格;

如果前面的指针指向的元素不等于val,那么两个指针都向前走一格。

再处理一些特殊情况:

cpp 复制代码
struct ListNode* removeElements(struct ListNode* head, int val) {
	ListNode * last = head;
	ListNode* tmp = head;
	if (last == NULL || (last->next == NULL && last->val == val))//如果是空链表或只有一个val的链表
	{
		return NULL;
	}
	else if (last->next == NULL)//如果只有一个节点且不等于val的链表
	{
		return head;
	}
	else
	{
		while (tmp != NULL)
		{
			if (tmp == last)
			{
				tmp = tmp->next;
			}
			if (tmp->val==val)
			{
				last->next = tmp->next;
				tmp = tmp->next;
			}
			else
			{
				last = last->next;
				tmp = tmp->next;
			}
		}
		if (head->val == val)//如果第一个节点的元素就等于val
		{
			return head->next;
		}
		last->next = NULL;
	}
	return head;
}

原题链接:

移除链表元素

✈反转链表

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

双指针法:

创建两个指针,一个在前,一个在后。

每次循环,将前面的指针指向的链表指向在后面的指针,后面的指针赋值成前一个,前一个往下走一格。

cpp 复制代码
struct ListNode* reverseList(struct ListNode* head) {
	if (head == NULL || head->next == NULL)//如果只有一个或者没有节点
	{
		return head;
	}
	ListNode* pre = head->next;
	head->next = NULL;
	while (pre != NULL)
	{
		ListNode* tmp = pre->next;
		pre->next = head;
		head = pre;
		pre = tmp;
	}
	return head;
}

原题链接:

反转链表

✈合并两个有序链表

双指针法:

创建三个指针,一个指向第一个链表,一个指向第二个链表,一个指向新链表的末尾。

如果第一个指针指向的元素比第二个指针小,那么就让新链表的末尾指向第一个指针,第一个指针再向后移一格,第三个指针向后移一格;

如果第二个指针指向的元素比第一个指针小,那么就让新链表的末尾指向第二个指针,第二个指针再向后移一格,第三个指针向后移一格。

cpp 复制代码
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
	if (list1 == NULL)//先解决其中存在空链表的情况
	{
		return list2;
	}
	else if (list2 == NULL)
	{
		return list1;
	}
	else
	{
		ListNode* pre = NULL;
		ListNode* finnal = NULL;
		if (list1->val <= list2->val)//初始化pre,确定新链表的的头节点finnal
		{
			finnal = list1;
			pre = list1;
			list1 = list1->next;
		}
		else
		{
			finnal = list2;
			pre = list2;
			list2 = list2->next;
		}
		while (list1 != NULL && list2 != NULL)//取元素到新的链表中
		{
			
			if (list1->val <= list2->val)
			{
				pre->next = list1;
				pre = list1;
				list1 = list1->next;
			}
			else
			{
				pre->next = list2;
				pre = list2;
				list2 = list2->next;
			}
		}
		if (list1 == NULL)
		{
			pre->next = list2;
		}
		else
		{
			pre->next = list1;
		}
		return finnal;
	}
}

原题链接:

合并两个有序链表

✈链表的中间节点

快慢指针法:

创建两个指针,一个快指针,一个慢指针,两个指针初始值为链表的起点。快指针每次走两格,慢指针每次走一格。

如果链表中有奇数个节点,当快指针的下一个节点为NULL时,慢指针走到中间节点的位置;

如果链表中有偶数个节点,当快指针为NULL时,慢指针走到中间节点的位置。

cpp 复制代码
typedef struct ListNode ListNode;
struct ListNode* middleNode(struct ListNode* head) {
	ListNode* fast = head;
	ListNode* slow = head;
	while (1)
	{
		if (fast == NULL || fast->next == NULL)
		{
			return slow;
		}
		fast = fast->next;
		fast = fast->next;
		slow = slow->next;
	}

}

原题链接:

链表的中间节点

✈环形链表的约瑟夫问题

环形链表法:

创建一个n个节点的环形链表,并且第n个节点的存储的元素是n。

删去第m个的值,并且循环n-1次。

cpp 复制代码
typedef struct ListNode {
	int val;
	struct ListNode* next;
}ListNode;

int ysf(int n, int m) {
	ListNode* head = (ListNode*)malloc(sizeof(ListNode));
	assert(head);
	head->val = 1;
	head->next = head;
	ListNode* pre = head;
	for (int i = 2; i <=n; i++)
	{
		ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
		newnode->next = head;
		newnode->val = i;
		pre->next = newnode;
		pre = newnode;
	}
	for (int i = 0; i < n - 1; i++)
	{
		for (int j = 0; j < m-1; j++)
		{
			pre = pre->next;
		}
		pre->next = pre->next->next;
	}
	return pre->val;
}

原题链接:

环形链表的约瑟夫问题

相关推荐
CoovallyAIHub7 小时前
Moonshine:比 Whisper 快 100 倍的端侧语音识别神器,Star 6.6K!
深度学习·算法·计算机视觉
CoovallyAIHub8 小时前
速度暴涨10倍、成本暴降6倍!Mercury 2用扩散取代自回归,重新定义LLM推理速度
深度学习·算法·计算机视觉
CoovallyAIHub8 小时前
实时视觉AI智能体框架来了!Vision Agents 狂揽7K Star,延迟低至30ms,YOLO+Gemini实时联动!
算法·架构·github
CoovallyAIHub8 小时前
开源:YOLO最强对手?D-FINE目标检测与实例分割框架深度解析
人工智能·算法·github
CoovallyAIHub9 小时前
OpenClaw:从“19万星标”到“行业封杀”,这只“赛博龙虾”究竟触动了谁的神经?
算法·架构·github
刀法如飞9 小时前
程序员必须知道的核心算法思想
算法·编程开发·算法思想
徐小夕10 小时前
pxcharts Ultra V2.3更新:多维表一键导出 PDF,渲染兼容性拉满!
vue.js·算法·github
CoovallyAIHub11 小时前
OpenClaw一脚踩碎传统CV?机器终于不再只是看世界
深度学习·算法·计算机视觉
CoovallyAIHub11 小时前
仅凭单目相机实现3D锥桶定位?UNet-RKNet破解自动驾驶锥桶检测难题
深度学习·算法·计算机视觉