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

✈移除链表元素

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

方法一:

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

方法二:

双指针

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

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

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

再处理一些特殊情况:

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 ,请你反转链表,并返回反转后的链表。

双指针法:

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

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

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;
}

原题链接:

反转链表

✈合并两个有序链表

双指针法:

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

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

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时,慢指针走到中间节点的位置。

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次。

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;
}

 原题链接:

环形链表的约瑟夫问题

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-30 00:02:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-30 00:02:02       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-30 00:02:02       87 阅读
  4. Python语言-面向对象

    2024-04-30 00:02:02       96 阅读

热门阅读

  1. ns模拟器+资源

    2024-04-30 00:02:02       33 阅读
  2. 【Spring AI】03. 开始

    2024-04-30 00:02:02       31 阅读
  3. Dubbo 面试题(十一)

    2024-04-30 00:02:02       29 阅读
  4. 「PHP系列」PHP Exception(异常处理)

    2024-04-30 00:02:02       38 阅读
  5. LeetCode 239. 滑动窗口最大值

    2024-04-30 00:02:02       36 阅读
  6. 2024.4.29力扣刷题记录-数组篇记录4

    2024-04-30 00:02:02       38 阅读
  7. 三层交换机原理

    2024-04-30 00:02:02       29 阅读
  8. 虚拟DOM

    虚拟DOM

    2024-04-30 00:02:02      38 阅读