【算法训练营】(day4)

这篇博客详细介绍了三种核心的链表操作:使用翻转技巧处理链表、合并两个有序链表以及删除链表中的重复元素。解题思路包括定义指针并处理临界条件,确保在各种情况下正确操作链表。通过实例代码展示了如何在不同场景下高效地操作链表数据结构。
摘要由CSDN通过智能技术生成

核心考点:链表操作,思维缜密程度

在这里插入图片描述

解题思路:
定义三个指针,整体右移,边移动,边翻转,保证不会断链,这里我们要注意分别只有一个节点,两个节点和多个节点的情况。

class Solution {
public:
	ListNode* ReverseList(ListNode* pHead) {
		if (pHead == NULL || pHead->next == NULL)
		{
			return pHead;
		}
		ListNode* first = pHead;
		ListNode* second = first->next;
		ListNode* third = second->next;
		while (third){
			//翻转
			second->next = first;
			//指针整体后移
			first = second;
			second = third;
			third = third->next;
		}
		second->next = first;//当传入的链表只有两个节点或者上述翻转结束最后一个并没有翻转
		pHead->next = nullptr;
		pHead = second;
		return pHead;
	}
};

核心考点:链表合并

在这里插入图片描述

解题思路:
在一个链表中插来插去比较混乱,这里我们定义一个新的链表,将数据往里插。

struct ListNode {
	int val;
	struct ListNode *next;
};

struct ListNode* merge(struct ListNode* l1, struct ListNode* l2)
{
	struct ListNode* guard = (struct ListNode*)malloc(sizeof(struct ListNode));//申请一个头结点
	struct ListNode* tail = guard;//尾指针
	struct ListNode* cur1 = l1;//记录当前遍历到的l1链表的结点位置
	struct ListNode* cur2 = l2;//记录当前遍历到的l2链表的结点位置
	while (cur1&&cur2)//当l1,l2中有一个链表遍历完毕时便停止
	{
		//取小的结点尾插到新链表后面
		if (cur1->val < cur2->val)
		{
			tail->next = cur1;
			cur1 = cur1->next;
		}
		else
		{
			tail->next = cur2;
			cur2 = cur2->next;
		}
		tail = tail->next;//结点增加,尾指针后移
	}
	//将未遍历完的链表的剩余结点接到新链表后面
	if (cur1)
		tail->next = cur1;
	else
		tail->next = cur2;

	struct ListNode* head = guard->next;
	free(guard);
	return head;
}

核心考点:链表操作,临界条件检查,特殊情况处理

在这里插入图片描述
解题思路
通过快慢指针的方式,进而达到去重的结果这里要考虑特别多的特殊情况,如:全部相同,全部不相同,部分相同等,为了方便解题我们定义头结点,主要是应对全部。相同的情况。

class Solution {
public:
	ListNode* deleteDuplication(ListNode* pHead) {
		if (pHead == NULL)
		{
			return pHead;
		}
		ListNode* head = new ListNode(0);
		head->next = pHead;
		ListNode* prev = head;
		ListNode* last = prev->next;
		while (last!=NULL)
		{
			//1.确立重复区域的起始位置
			while (last->next != NULL&&last->val != last->next->val)
			{
				prev = last;
				last = last->next;
			}
			//2.确立重复区域
			while (last->next != NULL&&last->val == last->next->val)
			{
				last = last->next;
			}
			if (prev->next != last)
			{
				prev->next = last->next;
			}
			last = last->next;
		}

	}
};
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值