1.环形链表
像这样本该是尾节点的地方又连接到了链表中的一个节点就形成环形链表
1)判断链表是否存在环
例题181.
给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true 。 否则,返回 false 。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/linked-list-cycle
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
定义一个快慢指针,快指针一回走两格,慢指针一回走一格,每一次快指针和慢指针距离+1,当链表成环形将会产生追及问题,快指针和慢指针会相遇,则当他们相遇时代表存在环形链表
class Solution {
public:
bool hasCycle(ListNode *head)
{
ListNode* fast = head;
ListNode* slow = head;
while(fast != NULL)
{
slow = slow->next;
fast=fast->next;
if(fast == NULL)
break;
fast = fast->next;
if(fast == slow)
{
return true;
}
}
return false;
}
};
2)判断环的大小
思路:
当第一次相遇时继续移动指针,当产生第二次相遇中间移动的次数即环的大小
2.反转链表
例题206.
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
思路:
双指针法
class Solution {
public:
ListNode* reverseList(ListNode* head)
{
ListNode* pointer1 = NULL;
ListNode* pointer2 = head;
while(pointer2 != NULL)
{
ListNode* temp = pointer2->next;
pointer2->next = pointer1;
pointer1 = pointer2;
pointer2 = temp;
}
return pointer1;
}
};
3.删除指定元素
例题203
给你一个链表的头节点 head
和一个整数 val
,请你删除链表中所有满足 Node.val == val
的节点,并返回 新的头节点 。
思路:
添加一个虚拟头节点,然后从虚拟头节点进行遍历。如果该节点下一个值等于目标值则该节点指向下下个节点
class Solution {
public:
ListNode* removeElements(ListNode* head, int val)
{
ListNode* fakeHead = (ListNode*)malloc(sizeof(ListNode));
fakeHead->next = head;
ListNode* temp = fakeHead;
while(temp->next != NULL)
{
if(temp->next->val == val)
{
temp->next = temp->next->next;
}
else
{
temp = temp->next;
}
}
return fakeHead->next;
}
};
4.删除重复元素
例题83
给定一个已排序的链表的头 head
, 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。
思路:
双重遍历寻找重复元素并删除
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head)
{
ListNode* pointer1 = head;
ListNode* pointer2 = head;
while(pointer1 != NULL&&pointer2 != NULL)
{
while(pointer2->next != NULL)
{
while(pointer2->next->val == pointer1->val)
{
ListNode* temp1 = pointer2->next->next;
pointer2->next = temp1;
//防止删除连续重复元素造成空指针
if(pointer2->next == NULL)
{
break;
}
}
pointer2 = pointer2->next;
if(pointer2 == NULL)
{
break;
}
}
pointer1 = pointer1->next;
pointer2 = pointer1;
}
return head;
}
};