day4 大纲
-
- 两两交换链表中的节点
- 19.删除链表的倒数第N个节点
- 面试题 02.07. 链表相交
- 142.环形链表II
- 总结
思路
细节
代码
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummy = new ListNode();
dummy.next = head;
ListNode cur = dummy, tmp;
while (cur.next != null && cur.next.next != null) {
ListNode n1 = cur.next;
ListNode n2 = cur.next.next;
n1.next = n2.next;
n2.next = n1;
cur.next = n2;
cur = n1;
}
return dummy.next;
}
}
思路
- 双指针法
- 设置快慢指针 快指针先走k步 快指针遍历到结束时慢指针的位置即为要删除的结点
细节
代码
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode();
dummy.next = head;
ListNode slow = dummy, fast = dummy;
while (fast != null) {
fast = fast.next;
if (n-- < 0) slow = slow.next;
}
slow.next = slow.next != null ? slow.next.next : null;
return dummy.next;
}
}
面试题 02.07. 链表相交
链表相交
思路
细节
- 交错链表发生在每个指针遍历完当前链表再去遍历另一链表 故而可通过三目运算简化代码
代码
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode p = headA, q = headB;
while (p != q) {
p = p == null ? headB : p.next;
q = q == null ? headA : q.next;
}
return p;
}
}
leetcode 142
环形链表II
思路
- 双指针法
- 设置快慢指针 快指针每次走两步 慢指针每次走一步
- 当快慢指针相遇时必定处于环中 从此结点开始走到环开始的结点的路程 = 从头结点走到环开始的结点
- 推导
- 设头结点到环开始结点的路程为x, 环开始结点到相遇结点的路程为y,相遇结点到环开始结点的路程为z(注意有向)
- 那么 慢指针的路程
x + y
快指针的路程 x + y + n(y + z)
n为转了n圈 设其为1 - 根据两指针的速度关系 有
2 * (x + y) = x + 2y + z
x = z
由此式子设置两指针分别指向头结点和相遇结点, 逐步遍历, 当二者相遇即为头结点
细节
- 注意边界条件,空链表或链表中只有一个元素的情况下保持代码的鲁棒性
代码
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode slow = head, fast = head;
while (fast != null && fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
ListNode n1 = head, n2 = fast;
while (n1 != n2) {
n1 = n1.next;
n2 = n2.next;
}
return n1;
}
}
return null;
}
}
总结