> For the complete documentation index, see [llms.txt](https://luckycurvec.gitbook.io/java-knowledge-architecture/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://luckycurvec.gitbook.io/java-knowledge-architecture/mian-shi-17/leetcode/lian-biao.md).

# Leetcode 链表

链表当中有相当一部分题目需要使用双指针的方式来进行解决，双指针标准Java代码：

```java
ListNode fast = head, slow = head;

while (fast != null && fast.next != null) {
    fast = fast.next.next;
    slow = slow.next;
    
    // TODO
}

// TODO
```

1、获取倒数第K个元素：快慢指针，fast先走K步，然后返回slow指针即可

2、获取中间位置的元素：快慢指针，返回slow

3、判断是否有环：快慢指针，先走，碰撞了之后返回true

4、寻找环入口，如果不存在就返回null

```java
public ListNode detectCycle(ListNode head) {
    ListNode fast = head, slow = head;

    while (true) {
        if (fast == null || fast.next == null) {
            return null;
        }
        slow = slow.next;
        fast = fast.next.next;

        if (fast == slow) {
            break;
        }
    }

    fast = head;

    while (fast != slow) {
        fast = fast.next;
        slow = slow.next;
    }

    return fast;
}
```

5、找到相交链表

```java
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    ListNode curA = headA, curB = headB;
    while (curA != curB) {
        curA = curA == null ? headB : curA.next;
        curB = curB == null ? headA : curB.next;
    }

    return curA;
}
```

反转链表类，都只需要在外部定义pre和cur即可

6、反转链表

```java
public ListNode reverseList(ListNode head) {
    ListNode pre = null, cur = head;

    while (cur != null) {
        ListNode temp = cur.next;
        cur.next = pre;

        pre = cur;
        cur = temp;
    }

    return pre;
}
```

7、反转链表Ⅱ：反转left到right的元素【头插法来解决】

```java
public ListNode reverseBetween(ListNode head, int left, int right) {
    // 防止left为1，使用虚拟头结点来解决
    ListNode virtualNode = new ListNode();

    virtualNode.next = head;

    ListNode pre = virtualNode, cur;
    for (int i = 0; i < left - 1; i++) {
        pre = pre.next;
    }

    cur = pre.next;

    for (int i = left; i < right; i++) {
        ListNode next = cur.next;
        cur.next = next.next;
        next.next = pre.next;
        pre.next = next;
    }

    return virtualNode.next;
}
```

> 头插法关键代码：
>
> ```java
> ListNode next = cur.next;
> cur.next = next.next;
> next.next = pre.next;	// 注意，千万不能写成cur，因为这里cur没有跟着走
> pre.next = next;
> ```

![image-20211005174813148](https://gitee.com/LuckyCurve/img/raw/master//img/image-20211005174813148.png)
