24. 两两交换链表中的节点
题目链接: https://leetcode.cn/problems/swap-nodes-in-pairs/
解题思路:
这个题目适合在本子上,先画四个数,模拟演练过程,过程演练明白了,代码思路就可以 清楚一些 .
如图:
色红孩子 虚拟头结点 pre, pre的下一个结点是curr,是真正的头结点, curr的下下一个结点是temp.
设置temp的目的是,保存该节点,防止1和2结点交换的过程中, 最后和3无法通过next建立联系了.
单向链表的每个结点 只有一个指针,通过next方法实现. 可以想象,当你使用next方法和其他节点构成指向关系的时候,其实原有的指向关系就会丧失. 比如,让1指向0, 1和2之间的指向关系就会丧失.
所以,图中的圈圈1,2,3 的先后顺序关系也是重要的.
前三行代码,对应图中的 圈圈1,2,3.
curr.next.next=curr;
pre.next=curr.next;
curr.next=temp;
链表节点通过next 建立起指向关系后,就要移动到1,2之后的下一轮节点了.
思考最开始的pre 和curr出在什么样的相对位置上,就可以向后移动了.
pre= curr;
curr=curr.next;

答案:
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummy = new ListNode(0,head );
ListNode pre = dummy;
ListNode curr = head;
ListNode temp = null;
// curr 和 curr.next 不为空
while (pre.next != null && pre.next.next != null) {
temp = curr.next.next;
// 先建立哪个关系
curr.next.next=curr;
pre.next=curr.next;
curr.next=temp;
pre= curr;
curr=curr.next;
}
return dummy.next;
}
}
19.删除链表的倒数第N个节点
题目链接:
利用快慢指针来做. 倒数第N个节点,先让快指针先遍历n次,在同时遍历 快慢指针,直至快指针到达尾部(不为null的结点),此时慢指针到达 欲删除结点的前一个结点,通过常规操作 slow.next=slow.next.next 来完成删除.
我出现的错误 : 我在创建快慢指针和 虚拟头结点的时候出错了,代码如下:
// ListNode fast=new ListNode(0,head);
// ListNode slow=new ListNode(0,head);
// ListNode dummy=new ListNode(0,head);
参考答案:
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
// ListNode fast=new ListNode(0,head);
// ListNode slow=new ListNode(0,head);
// ListNode dummy=new ListNode(0,head);
ListNode dummy=new ListNode(0,head);
ListNode fast=dummy;
ListNode slow=dummy;
while (n> 0){
fast=fast.next;
n--;
}
while (fast.next !=null){
fast=fast.next;
slow=slow.next;
}
slow.next=slow.next.next;
return dummy.next;
}
}
面试题 02.07. 链表相交
题目链接: 面试题 02.07. 链表相交 - 力扣(LeetCode)
长短的两个链表如果能相交, 意味着,求出两个链表的长度差 num,让长的链表领先遍历num 个位置,再让长短链表一起遍历,遇到结点相等的时候,就可以返回对应结点了.
犯错的地方:
1.遇到结点相等的时候,直接让两个结点相等,他们的地址值也相等,而不是值val相等.
2.开始用的是currA 和 currB 遍历,获取链表长度,后面直接用的 headA 和headB 进行操作,测试用例只能覆盖两个.

参考答案:
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode currA = headA;
ListNode currB = headB;
int numA = 0;
int numB = 0;
while (currA != null) {
currA = currA.next;
numA++;
}
while (currB != null) {
currB = currB.next;
numB++;
}
currA = headA;
currB = headB;
if (numA < numB) {
ListNode temp = currA;
currA = currB;
currB = temp;
int num = numA;
numA = numB;
numB = num;
}
int number = numA - numB;
while (number > 0) {
currA=currA.next;
number--;
}
while (currA!=null) {
if (currA==currB){
return currA;
}
currA=currA.next;
currB=currB.next;
}
return null;
}
}
142.环形链表II
题目链接: https://leetcode.cn/problems/linked-list-cycle-ii/
解题思路:
从数学角度证明,从环相交的位置开始,一个结点从环相交位置开始,一个从头结点开始,相同速度遍历,相遇的地方,两结点相等的地方,就是环入口位置.

错误:
本题目用了虚拟头结点,用例直接没通过几个.
ListNode listNode = new ListNode(0, head);
ListNode fast = listNode;
ListNode slow = listNode;
参考答案:
public class Solution {
public ListNode detectCycle(ListNode head) {
// ListNode listNode = new ListNode(0, head);
ListNode fast = head;
ListNode slow = head;
while (fast!=null && fast.next!=null){
fast=fast.next.next;
slow=slow.next;
if(fast==slow ){
ListNode index_fast=fast;
ListNode index_slow=head;
while (index_fast != index_slow) {
index_fast=index_fast.next;
index_slow=index_slow.next;
}
return index_fast;
}
}
return null;
}
}