文章目录
day04学习内容
day04主要内容
- 两两交换链表中的节点
- 删除倒数第N个节点
- 链表相交
- 环形链表
一、 两两交换链表中的节点
1.错误写法1
class Solution {
public ListNode swapPairs(ListNode head) {
if(head==null){
return null;
}
ListNode dummy = new ListNode(-1,head);
ListNode cur = dummy;
while(cur.next!=null&&cur.next.next!=null){
ListNode tempNode1 = cur.next;
ListNode tempNode2 = cur.next.next;
ListNode tempNode3 = cur.next.next.next;
cur.next = tempNode2;
tempNode2.next = tempNode1;
tempNode1.next = tempNode3;
cur = tempNode2; //注意就是这一句话写错了,为什么错了,看下面分析
}
return dummy.next;
}
}
假如head = 1->2->3->4->null,代码执行到tempNode1.next = tempNode3这一步时,此时链表的变化过程如下俩图(数字就是交换的执行顺序),
因为要让cur重新指向需要交换的2个节点的前1个节点,此时节点【3】的前一个节点是【1】,所以此时cur=N1而不是cur=N2
2.正确写法1
class Solution {
public ListNode swapPairs(ListNode head) {
if(head==null){
return null;
}
ListNode dummy = new ListNode(-1,head);
ListNode cur = dummy;
while(cur.next!=null&&cur.next.next!=null){
ListNode tempNode1 = cur.next;
ListNode tempNode2 = cur.next.next;
ListNode tempNode3 = cur.next.next.next;
cur.next = tempNode2;
tempNode2.next = tempNode1;
tempNode1.next = tempNode3;
cur = tempNode1;
}
return dummy.next;
}
}
2.正确写法2
`采用双指针
class Solution {
public ListNode swapPairs(ListNode head) {
if(head==null){
return null;
}
ListNode dummy = new ListNode(-1,head);
ListNode cur = dummy;
while(cur.next!=null&&cur.next.next!=null){
ListNode tempNode1 = cur.next;
ListNode tempNode3 = cur.next.next.next;
cur.next = cur.next.next;
cur.next.next = tempNode1;//注意这里不要写成cur.next.next.next了,画图理解一下就知道为什么要这么写了
tempNode1.next = tempNode3;
cur = tempNode1;
}
return dummy.next;
}
}
二、删除倒数第N个节点(双指针法)
思路:
这一题主要是想明白,怎么找到倒数第N个节点。
- 问题1:
我就没想到快指针要先走N+1步,看了题解和视频才看明白的,才知道这个思路 - 问题2
先让快指针走n步,不知道怎么写代码。。。离天下之大谱 - 问题3
不知道怎么让fast和slow同时移动,直到fast==null终止
好家伙,很简单的一题就有三个问题了,基本等于一句都不会写。
1.正确写法1
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(-1,head);
ListNode fast = dummy;
ListNode slow = dummy;
for(int i=0;i<=n;i++){
fast = fast.next;
}
while(fast!=null){
fast = fast.next;
slow = slow.next;
}
slow.next= slow.next.next;
return dummy.next;
}
}
三、链表相交
1.正确写法-双指针
略
四、环形链表
1.思考
- 核心思路
-
判断是否有环:fast==slow,就说明有环
-
怎么找到相遇节点:index1=index2,即从头结点出发一个指针,从相遇节点 也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候就是 环形入口的节点。
-疑问1:在相遇节点处定义一个指针,为什么这个指针index1=fast?
解释:因为是用快指针作为桥梁的,所以肯定是fast
-疑问2:为什么index=head?
2.正确写法
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) {// 相遇
ListNode index1 = fast;
ListNode index2 = head;
while (index1 != index2) {
index1 = index1.next;//不要写成index1=fast.next了
index2 = index2.next;
}
return index1;
}
}
return null;
}
}
总结
1.感想
- 俩俩交互节点和删除倒数第N个节点,很容易写着写着就把指针搞错了,建议写代码一定要画图理解
- 环形链表代码不难,思路很难,不看题解我是完全想不到的。
2.思维导图
本文思路引用自代码随想录,感谢代码随想录作者。