LeetCode 24-两两交换链表中的节点
题目链接:
https://leetcode.cn/problems/swap-nodes-in-pairs/submissions/
解题思路:
用虚拟节点cur两两交换,返回虚拟头节点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mh1hhpy0-1665908914836)(https://code-thinking.cdn.bcebos.com/pics/24.%E4%B8%A4%E4%B8%A4%E4%BA%A4%E6%8D%A2%E9%93%BE%E8%A1%A8%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B91.png)]
代码实现
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dum = new ListNode();
dum.next = head;
ListNode cur = dum;
while (cur.next != null && cur.next.next != null) {
ListNode temp1 = cur.next;
ListNode temp2 = cur.next.next.next;
cur.next = cur.next.next;
cur.next.next = temp1;
cur.next.next.next = temp2;
cur = cur.next.next;
}
return dum.next;
}
}
难点:
-
操作的指针一定指向要反转的两个节点中的前一个结点
-
cur = dum?:cur指向dum才能操作头结点和第二个结点 因为要返回head指针所以要保留dum
-
while里的条件为什么不能是(cur.next.next != null && cur.next != null)?:
一定要先判断cur.next不为空,再判断cur.next.next不为空,因为万一cur.next为空,则cur.next.next中的cur.next就是对空指针取值再找他的next域,会报空指针异常
-
结点偶数:cur.next == null(链表为空时)
-
结点奇数:cur.next.next == null
-
while条件相当于cur后必须有两节点,少于2个无法交换,循环就结束了,无论节点是奇数还是偶数
-
cur要移到需要操作的两个节点的前一个结点
-
移节点时为什么是cur = cur.next.next?:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pXKlZgks-1665908914837)(C:\Users\Cl\AppData\Roaming\Typora\typora-user-images\image-20221015205528424.png)]
LeetCode 19-删除链表的倒数第N个结点
题目链接:
https://leetcode.cn/problems/remove-nth-node-from-end-of-list/
解题思路:
双指针的经典应用,如果要删除倒数第n个节点,让fast移动n+1步,然后让fast和slow同时移动,直到fast指向链表末尾,删掉slow.next所指向的结点。
代码实现
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dum = new ListNode();
dum.next = head;
ListNode fast = dum;
ListNode slow = dum;
n++;
while (n != 0 && fast != null) {
fast = fast.next;
n--;
}
while (fast != null) {
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dum.next;
}
}
难点:
-
为什么fast走n+1步而不是走n步?:如果fast走n步,slow指向要删除的结点,但是slow应该指向要删除的结点的前驱,因为需要利用 要删除的节点的前驱 来删除倒数第n个结点。
-
为什么不这样写?:
while(n != 0 && fast != null) { fast = fast.next; n--; } fast = fast.next;//如果n>链表的长度,则fast指向null,则fast.next是对空指针操作 会报错
LeetCode 面试题02.07.链表相交
题目链接:
https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/
解题思路:
定义两个cur指针分别指向链表头。让curA移到curB末尾对齐的位置,再比较如果相同返回curA 都不相同返回null
代码实现
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dum = new ListNode();
dum.next = head;
ListNode fast = dum;
ListNode slow = dum;
n++;
while (n != 0 && fast != null) {
fast = fast.next;
n--;
}
while (fast != null) {
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode curA = headA;
ListNode curB = headB;
int lenA = 0;
int lenB = 0;
while (curA != null) {
lenA++;
curA = curA.next;
}
while (curB != null) {
lenB++;
curB = curB.next;
}
curA = headA;
curB = headB;
if (lenB > lenA) {
int tempL = lenA;
lenA = lenB;
lenB = tempL;
ListNode tempN = curA;
curA = curB;
curB = tempN;
}
int gap = lenA - lenB;
while (gap != 0) {
curA = curA.next;
gap--;
}
while (curA != null) {
if (curA == curB) {
return curA;
}
curA = curA.next;
curB = curB.next;
}
return null;
}
}
难点:
- 如果链表B比链表A长要交换头指针的原因:如果A链表一定是长的那条,则只要写一种方法,而不用讨论链表B比链表A长的情况
- 让cur移动到和curB末尾对齐的位置的原因:如果有一个节点相交,则这个节点之后的所有节点都是相交的 只要判断第一个相交的节点
- 遍历curA和curB 要先保证curA或者curB不是空指针,所以最后一个while循环里的条件是判断curA不为空
LeetCode 142.环形链表II
题目链接:
https://leetcode.cn/problems/linked-list-cycle-ii/
解题思路:
判断链表是否有环
用快慢指针 fast每次2步 slow每次1步 如果fast和slow在途中相遇则链表有环
找到环的入口
两个指针,从头结点和相遇结点,各走一步,直到相遇,相遇点即为环入口
代码实现
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
ListNode index1 = fast;
ListNode index2 = head;
while (index1 != index2) {
index1 = index1.next;
index2 = index2.next;
}
return index2;
}
}
return null;
}
}
难点:
- 革命尚未成功同志还需努力T-T难点太多了omg
- https://programmercarl.com/0142.%E7%8E%AF%E5%BD%A2%E9%93%BE%E8%A1%A8II.html#_142-%E7%8E%AF%E5%BD%A2%E9%93%BE%E8%A1%A8ii