目录
24. 两两交换链表中的节点
19. 删除链表的倒数第 N 个结点
面试题 02.07. 链表相交
142. 环形链表 II
24. 两两交换链表中的节点
24. 两两交换链表中的节点
难度:medium
类型:链表

思路:
代码:
class Solution {
    public ListNode swapPairs(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode dummy = new ListNode(-1, head);
        ListNode cur = dummy;
        ListNode tem1 = null;
        ListNode tem2 = null;
        while (cur.next != null && cur.next.next != null) {
            tem1 = cur.next;
            tem2 = cur.next.next;
            tem1.next = tem2.next;
            tem2.next = tem1;
            cur.next = tem2;
            cur = tem1;
        }
        return dummy.next;
    }
} 
复杂度分析:
- 时间复杂度:O(n)
 - 空间复杂度:O(1)
 
19. 删除链表的倒数第 N 个结点
难度:medium
类型:链表

思路:
代码:
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        if (head == null || n == 0) {
            return head;
        }
        ListNode dummy = new ListNode(-1, head);
        ListNode cur1 = dummy;
        ListNode cur2 = dummy;
        for (int i = 0; i <= n; i++) {
            cur2 = cur2.next;
        }
        while (cur2 != null) {
            cur1 = cur1.next;
            cur2 = cur2.next;
        }
        cur1.next = cur1.next.next;
        return dummy.next;
    }
} 
复杂度分析:
- 时间复杂度:O(n)
 - 空间复杂度:O(1)
 
面试题 02.07. 链表相交
面试题 02.07. 链表相交
难度:easy
类型:链表
 
思路:
代码:
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if (headA == null || headB == null) {
            return null;
        }
        // 计算链表A,B的长度
        int lenA = 0;
        ListNode curA = headA;
        while (curA != null) {
            lenA++;
            curA = curA.next;
        }
        int lenB = 0;
        ListNode curB = headB;
        while (curB != null) {
            lenB++;
            curB = curB.next;
        }
        // 若A比B长,则交换链表A和B的头结点名称,使headB始终代表更长的链表
        if (lenA > lenB) {
            ListNode tem = headA;
            headA = headB;
            headB = tem;
        }
        // 记住加绝对值
        int gap = Math.abs(lenB - lenA);
        // 链表对齐
        while (gap-- > 0) {
            headB = headB.next;
        }
        while (headA != headB) {
            headA = headA.next;
            headB = headB.next;
            // 没有相交
            if (headA == null) {
                return null;
            }
        }
        return headA;
       
    }
}
 
复杂度分析:
- 时间复杂度:O(n)
 - 空间复杂度:O(1)
 
142. 环形链表 II
142. 环形链表 II
难度:medium
类型:链表

思路:
代码:
public class Solution {
    public ListNode detectCycle(ListNode head) {
        // 链表为空或者只有一个节点
        if (head == null || head.next == null) {
            return null;
        }
        // 快指针一次走两步,慢指针走一步
        ListNode fast = head;
        ListNode slow = head;
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
            // 链表相交
            if (fast == slow) {
                // 寻找环入口,起点和交点同时出发的指针会在环入口相遇
                ListNode cur = head;
                while (cur != fast) {
                    cur = cur.next;
                    fast = fast.next;
                } 
                return cur;
            }
        }
        return null;
    }
} 
                




![[极客大挑战 2019]PHP(反序列化)](https://img-blog.csdnimg.cn/ed7befb0d79847128e142421ffda6f4b.png)














