链表的一大问题就是操作当前节点必须要找前一个节点才能操作。这就造成了,头结点的尴尬,因为头结点没有前一个节点了。
每次对应头结点的情况都要单独处理,所以使用虚拟头结点的技巧,就可以解决这个问题。
24. 两两交换链表中的节点 (临时结点)
用虚拟头结点和temp保存临时结点。注意循环终止条件
题目链接/文章讲解/视频讲解: 代码随想录
//dummyhead
//保存临时结点
//要修改一个结点指向,一定要知道前一个结点的指针
//while循环终止条件
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode cur = dummy;
//链表结点数为偶数时,cur.next = null,结束循环
//链表结点数为奇数时,cur.next.next = null,结束循环
//或者理解为cur后面要有两个结点,少于就结束循环
while(cur.next != null && cur.next.next != null) {
//这里设置两temp是为了防止丢失连接
ListNode temp1 = cur.next;
//要在第一条线还没断开时候就保存。
ListNode temp2 = cur.next.next.next;
cur.next = cur.next.next;
cur.next.next = temp1;
temp1.next = temp2;
cur = cur.next.next;
}
return dummy.next;
}
}
19.删除链表的倒数第N个节点 (快慢指针)
双指针的操作,要注意,删除第N个节点,那么我们当前遍历的指针一定要指向 第N个节点的前一个节点。
题目链接/文章讲解/视频讲解:代码随想录
//双指针(快慢), fast和slow初始都为dummy
//找n节点: fast首先走n + 1步
//只有这样同时移动的时候slow才能指向删除节点的上一个节点(方便做删除操作)
//确定好fast和slow相隔n + 1后再一起走(用while和.next)
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
//定义dummy head
ListNode dummy = new ListNode(0, head);
//定义快慢指针
ListNode fast = dummy, slow = dummy;
//fast先走n+1
while(n + 1 > 0 && fast != null) {
fast = fast.next;
n--;
}
//fast, slow一起走。 while结束,fast指向Null
while(fast != null) {
fast = fast.next;
slow = slow.next;
}
//删除
slow.next = slow.next.next;
return dummy.next;
}
}
160. Intersection of Two Linked Lists
数值相同,不代表指针相同。
题目链接/文章讲解:代码随想录
//双指针暴力解法
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
while (headA != null) {
ListNode pB = headB;
//遍历B链表
while (pB != null) {
if (headA == pB) return headA;
pB = pB.next;
}
//遍历A链表
headA = headA.next;
}
return null;
}
}
142.环形链表II (比较难)
算是链表比较有难度的题目,需要多花点时间理解 确定环和找环入口,建议先看视频。
题目链接/文章讲解/视频讲解:代码随想录
//快慢指针,fast走2步,slow走1步,相等则相遇有环。
//相遇点和头结点,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候就是 环形入口的节点
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast = head, slow = head;
//因为fast走2步,所以还要判断fast.next不为空
while(fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if(fast == slow) {
ListNode index1 = fast;
ListNode index2 = head;
//此时从head 和 相遇点,同时查找直至相遇
while(index1 != index2) {
index1 = index1.next;
index2 = index2.next;
}
return index1;
}
}
//别忘了
return null;
}
}
本文详细探讨了链表操作,包括如何两两交换链表中的节点、利用快慢指针删除链表的倒数第N个节点、找出两个链表的交点以及解决环形链表的难题。每个主题都提供了题目链接、文章讲解和视频教程,帮助读者深入理解链表操作的关键技巧和注意事项。

被折叠的 条评论
为什么被折叠?



