/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode swapPairs(ListNode head) {
if (head == null || head.next == null) return head;
ListNode newHead = new ListNode(-1, head);
ListNode l = newHead;
ListNode nex = l.next;
ListNode temp = null;
while (nex != null && nex.next != null) {
temp = nex;
nex = nex.next;
l.next = nex;
temp.next = nex.next;
nex.next = temp;
l = temp;
nex = l.next;
}
return newHead.next;
}
}
简单思路很好想,先遍历找到链表的长度,就可以根据n的值得知该节点是第size-n+1个结点。
但如何一遍遍历就删除节点,可以考虑双指针。我们希望当快指针遍历完整个链表时,慢指针刚好找到要删除的结点(或者要删除的结点的上一个),由于n是代表倒数第n个结点,不难发现,快指针和慢指针相差n + 1步时,满足上面的设想(上一个结点)。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
// 找size的做法
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode l = head;
int size = 0;
while (l != null) {
size ++;
l = l.next;
}
if (size == 1) return null;
// 删除第size - n + 1个节点
int count = size - n + 1;
ListNode newHead = new ListNode(-1, head);
ListNode pre = newHead;
for (int i = 0; i < count - 1; i ++) {
pre = pre.next;
}
pre.next = pre.next.next;
return newHead.next;
}
}
// 单次遍历的做法
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode newHead = new ListNode(-1, head);
ListNode slow = newHead;
ListNode fast = newHead;
// 让快指针先走n + 1步
for (int i = 0; i <= n; i ++) {
fast = fast.next;
}
while (fast != null) {
slow = slow.next;
fast = fast.next;
}
slow.next = slow.next.next;
return newHead.next;
}
}
两个指针分别指向两个链表的头部,开始遍历,本链表遍历完遍历另一个链表。如果没有相交,则会同时走到null,若有相交,则会同时走到相交的结点。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode A = headA, B = headB;
while (A != B) {
if (A != null) A = A.next;
else A = headB;
if (B != null) B = B.next;
else B = headA;
}
return A;
}
}
// 哈希表
public class Solution {
public ListNode detectCycle(ListNode head) {
Set<ListNode> s = new HashSet<>();
ListNode newHead = new ListNode(-1, head);
ListNode l = newHead;
while (l != null) {
if (s.contains(l)) {
return l;
}
s.add(l);
l = l.next;
}
return l;
}
}