链表--双指针--虚拟节点
- 力扣 142 环形链表求循环起点 重点
- 力扣 21 合并两个有序链表
- 力扣 86 分割链表
- 力扣23 合并K个有序链表 -- 优先队列(二叉堆 小顶堆)重点
- 力扣19 找倒数第N个元素 快慢指针 + 一次遍历 重点
- 力扣876 快慢指针找中间节点
- 力扣 160 相交链表 遍历“两遍”
- 辅助测试类
力扣 142 环形链表求循环起点 重点

public static ListNode detectCycle(ListNode head) {ListNode dummy = new ListNode(-1);dummy.next = head;ListNode fast = dummy;ListNode slow = dummy;ListNode newHead = dummy;boolean symbol = false;while (fast != null && fast.next != null) {fast = fast.next.next;slow = slow.next;if (slow == fast) {symbol = true;break;}}if (symbol) {while (newHead != slow) {newHead = newHead.next;slow = slow.next;}return newHead;} else {return null;}}
力扣 21 合并两个有序链表
public static ListNode mergeTwoLists(ListNode l1, ListNode l2) {ListNode dummy = new ListNode(-1);ListNode p = dummy;ListNode p1 = l1, p2 = l2;while (p1 != null && p2 != null) {if (p1.val < p2.val) {p.next = p1;p1 = p1.next;p = p.next;} else {p.next = p2;p2 = p2.next;p = p.next;}}if (p1 != null) {p.next = p1;}if (p2 != null) {p.next = p2;}return dummy.next;}
力扣 86 分割链表
public static ListNode partition(ListNode head, int x) {ListNode dummy1 = new ListNode(-1);ListNode dummy2 = new ListNode(-1);ListNode h = head;ListNode p1 = dummy1;ListNode p2 = dummy2;while (h != null) {if (h.val < x) {p1.next = h;h = h.next;p1 = p1.next;p1.next = null;} else {p2.next = h;h = h.next;p2 = p2.next;p2.next = null;}}p1.next = dummy2.next;return dummy1.next;}
力扣23 合并K个有序链表 – 优先队列(二叉堆 小顶堆)重点
public static ListNode mergeKLists(ListNode[] lists) {if (lists.length < 1) {return null;} else {PriorityQueue<ListNode> priorityQueue = new PriorityQueue<ListNode>(lists.length, new Comparator<ListNode>() {@Overridepublic int compare(ListNode o1, ListNode o2) {return o1.val - o2.val;}});ListNode dummy = new ListNode(-1); ListNode p = dummy;for (ListNode listNode : lists) {if (listNode != null) {priorityQueue.add(listNode);}}while (!priorityQueue.isEmpty()) {ListNode temp = priorityQueue.poll();p.next = temp;p = p.next;if (temp.next != null) {priorityQueue.add(temp.next); }}return dummy.next;}}
力扣19 找倒数第N个元素 快慢指针 + 一次遍历 重点
public static ListNode removeNthFromEnd(ListNode head, int n) {ListNode dummy = new ListNode(-1);dummy.next = head;ListNode p1 = dummy;ListNode p2 = dummy;for (int i = 0; i < n; i++) {p1 = p1.next;}if (p1 == null) {return null;}while (p1.next != null) {p1 = p1.next;p2 = p2.next;}ListNode p3 = p2.next.next;p2.next = p3;return dummy.next;}
力扣876 快慢指针找中间节点
public static ListNode middleNode(ListNode head) {ListNode dummy = new ListNode(-1);dummy.next = head;ListNode p1 = dummy;ListNode p2 = dummy;while (p1 != null) {p2 = p2.next;if (p1.next == null) {break;} else {p1 = p1.next.next;}}return p2;}
力扣 160 相交链表 遍历“两遍”
public static ListNode getIntersectionNode(ListNode headA, ListNode headB) {ListNode p = headA;ListNode q = headB;while (p != q) {if (p == null) {p = headB;} else {p = p.next;}if (q == null) {q = headA;} else {q = q.next;}}return p;}
辅助测试类
package com.caoii.LinkedList;public class ListNode {public int val;public ListNode next;ListNode() {}public ListNode(int val) {this.val = val;}ListNode(int val, ListNode next) {this.val = val;this.next = next;}
}
package com.caoii;import com.caoii.LinkedList.DoublePointerInLinkedList;
import com.caoii.LinkedList.ListNode;
import org.junit.jupiter.api.Test;public class DoublePointerTest {@Testpublic void test_01() {ListNode l1 = new ListNode(1);ListNode p1 = l1;p1.next = new ListNode(2);p1 = p1.next;p1.next = new ListNode(4);ListNode l2 = new ListNode(1);ListNode p2 = l2;p2.next = new ListNode(3);p2 = p2.next;p2.next = new ListNode(9);ListNode returnListNode = DoublePointerInLinkedList.mergeTwoLists(l1, l2);ListNode p = returnListNode;while (p != null) {System.out.print(p.val + " ");p = p.next;}System.out.println();}@Testpublic void test_02() {ListNode l1 = new ListNode(1);ListNode p1 = l1;p1.next = new ListNode(4);p1 = p1.next;p1.next = new ListNode(3);p1 = p1.next;p1.next = new ListNode(2);p1 = p1.next;p1.next = new ListNode(5);p1 = p1.next;p1.next = new ListNode(2);ListNode returnListNode = DoublePointerInLinkedList.partition(l1, 3);ListNode p = returnListNode;while (p != null) {System.out.print(p.val + " ");p = p.next;}System.out.println();}@Testpublic void test_03() {ListNode l1 = new ListNode(1);ListNode p1 = l1;p1.next = new ListNode(4);p1 = p1.next;p1.next = new ListNode(5);ListNode l2 = new ListNode(1);ListNode p2 = l2;p2.next = new ListNode(3);p2 = p2.next;p2.next = new ListNode(4);ListNode l3 = new ListNode(2);ListNode p3 = l3;p3.next = new ListNode(6);ListNode[] lists = new ListNode[]{l1, l2, l3};ListNode returnListNode = DoublePointerInLinkedList.mergeKLists(lists);ListNode p = returnListNode;while (p != null) {System.out.print(p.val + " ");p = p.next;}System.out.println();}@Testpublic void test_04() {ListNode l1 = new ListNode(1);ListNode p1 = l1;p1.next = new ListNode(2);p1 = p1.next;p1.next = new ListNode(3);p1 = p1.next;p1.next = new ListNode(4);p1 = p1.next;p1.next = new ListNode(5);ListNode returnListNode = DoublePointerInLinkedList.removeNthFromEnd(l1, 2);ListNode p = returnListNode;while (p != null) {System.out.print(p.val + " ");p = p.next;}System.out.println();}@Testpublic void test_05() {ListNode l1 = new ListNode(1);ListNode p1 = l1;p1.next = new ListNode(2);p1 = p1.next;p1.next = new ListNode(3);p1 = p1.next;p1.next = new ListNode(4);p1 = p1.next;p1.next = new ListNode(5);p1 = p1.next;p1.next = new ListNode(6);ListNode returnListNode = DoublePointerInLinkedList.middleNode(l1);ListNode p = returnListNode;while (p != null) {System.out.print(p.val + " ");p = p.next;}System.out.println();}@Testpublic void test_06() {ListNode l1 = new ListNode(3);ListNode p1 = l1;p1.next = new ListNode(2);p1 = p1.next;ListNode temp = p1;p1.next = new ListNode(0);p1 = p1.next;p1.next = new ListNode(-4);p1 = p1.next;p1.next = temp;ListNode returnListNode = DoublePointerInLinkedList.detectCycle(l1);ListNode p = returnListNode;System.out.println("循环起点的值:" + p.val);}@Testpublic void test_07() {ListNode l1 = new ListNode(-3);ListNode l2 = new ListNode(30);ListNode p1 = l1;ListNode p2 = l2;ListNode temp = new ListNode(300);ListNode p3 = temp;p3.next = new ListNode(400);p3 = p3.next;p3.next = new ListNode(500);p3 = p3.next;p1.next = new ListNode(-4);p1 = p1.next;p1.next = new ListNode(-5);p1 = p1.next;p1.next = temp;p2.next = new ListNode(40);p2 = p2.next;p2.next = new ListNode(50);p2 = p2.next;p2.next = new ListNode(60);p2 = p2.next;p2.next = temp;ListNode returnListNode = DoublePointerInLinkedList.getIntersectionNode(l1, l2);ListNode p = returnListNode;System.out.println("第一个交点的值:" + p.val);}
}