24.两两交换链表中节点(中)
题目链接:24.两两交换链表中节点
代码随想录:24.两两交换链表中节点
题目描述:给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
输入:head = [1,2,3,4]
输出:[2,1,4,3]
迭代法
ListNode* swapPairs(ListNode* head) {
ListNode * hNode = new ListNode;
hNode -> next = head;
ListNode * cur = hNode;
while(cur->next && cur->next->next){
ListNode * tmp1 = cur->next;
ListNode * tmp2 = cur->next->next;
cur->next = tmp1->next;
tmp1->next = tmp2->next;
tmp2->next = tmp1;
cur = tmp1;
}
return hNode->next;
}
递归法(无虚拟头结点)
ListNode* swapPairs(ListNode* head) {
if(!head ||!head->next){
return head;
}
//保存头结点的下一个节点
ListNode * cur = head -> next;
//将头结点的next指向head+2处,继续用递归
head -> next = swapPairs(cur->next);
//新的头结点的next指向旧的head
cur->next = head;
return cur;
}
19. 删除链表的倒数第 N 个结点(中)
LeetCode题目:19. 删除链表的倒数第 N
个结点
代码随想录:19. 删除链表的倒数第 N
个结点
题目描述:给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
//快慢指针
ListNode * dummy = new ListNode;
dummy -> next = head;
ListNode *slow = dummy;
ListNode *fast = dummy;
// fast - delete = n (fast 走到Null)
while(n--&& fast) //fast向前n+1步,因为slow是要删掉节点的前驱结点
fast = fast->next;
fast = fast->next;
while(fast){
fast = fast->next;
slow = slow->next;
}
//删掉slow的下一个
ListNode *tmp = slow->next;
slow->next = tmp->next;
delete tmp;
return dummy->next;
}
};
160.链表相交(简单)
LeetCode题目:160.链表相交
代码随想录:160.链表相交
题目描述:给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null
。 图示两个链表在节点 c1 开始相交:
题目数据 保证 整个链式结构中不存在环。 注意,函数返回结果后,链表必须 保持其原始结构 。
思路:先求出两个链表的长度之差,然后让长链表指针移动到和短链表开头位置
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
// 求出两个链表的长度,并求出两个链表长度的差值,然后让p移动到,和q末尾对齐的位置
ListNode * p = headA;
ListNode * q = headB;
int countA = 0, countB = 0;
while(p){
countA++;
p = p->next;
}
while(q){
countB++;
q = q->next;
}
p = headA;
q = headB;
// 保证A是长的链表
if(countA < countB){
swap(p, q);
swap(countA, countB);
}
int len = countA - countB;
while(len--){
p = p->next;
}
while(p){
if(p == q)
return p;
p = p->next;
q = q->next;
}
return NULL;
}
};
142.环形链表II(☆☆☆)
LeetCode题目:142.环形链表II
代码随想录:142.环形链表II
视频讲解:142.环形链表II
题目描述:给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。
注意:pos不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改链表。
快慢指针,fast步长为2,slow步长为1,若有环则fast和slow必相遇,且相遇位置到环入口的距离等于链表头结点到环入口的距离。
因此,快慢指针相遇时,头结点index与slow同时向后移动,相遇点即为环的入口。
n!=1也无妨,相遇点表示slow在环内转了n-1圈再与index相遇。
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast = head;
ListNode* slow = head;
while(fast && fast -> next){
fast = fast->next->next;
slow = slow->next;
//若相遇,则必有环
if(slow == fast){
ListNode * index = head;
while(1){
if(index == slow)
return index;
index = index->next;
slow = slow->next;
}
}
}
return NULL;
}
};