2、链表
1、移除链表元素
public ListNode removeElements(ListNode head, int val) {
ListNode dummyHead = new ListNode(-1, head);
ListNode prev = dummyHead;
while (prev.next != null) {
if (prev.next.val == val) prev.next = prev.next.next;
else prev = prev.next;
}
return dummyHead.next;
}
public static ListNode removeElements(ListNode head, int val) {
if (head == null) return null;
head.next = removeElements(head.next, val);
return head.val != val ? head : head.next;
}
2、设计链表
public class MyLinkedList {
private class Node {
int val;
Node next;
public Node() {
}
public Node(int val, Node next) {
this.val = val;
this.next = next;
}
}
private Node dummyHead;
int size;
public MyLinkedList() {
dummyHead = new Node();
size = 0;
}
public int get(int index) {
if (index < 0 || index >= size) return -1;
Node cur = dummyHead.next;
for (int i = 0; i < index; i++) {
cur = cur.next;
}
return cur.val;
}
public void addAtHead(int val) {
addAtIndex(0, val);
}
public void addAtTail(int val) {
addAtIndex(size, val);
}
public void addAtIndex(int index, int val) {
if (index < 0 || index > size) return;
Node prev = dummyHead;
for (int i = 0; i < index; i++) prev = prev.next;
prev.next = new Node(val, prev.next);
size++;
}
public void deleteAtIndex(int index) {
if (index < 0 || index >= size) return;
Node prev = dummyHead;
for (int i = 0; i < index; i++) {
prev = prev.next;
}
prev.next = prev.next.next;
size--;
}
}
3、反转链表
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode cur = head;
ListNode next;
while (cur != null) {
next = cur.next;
cur.next = prev;
prev = cur;
cur = next;
}
return prev;
}
public ListNode reverseList(ListNode node) {
if (node == null || node.next == null) return node;
ListNode head = reverseList(node.next);
node.next.next = node;
node.next = null;
return head;
}
4、两两交换链表中的节点
public ListNode swapPairs(ListNode head) {
if (head == null || head.next == null) return head;
ListNode dummyHead = new ListNode(-1, head);
// 1 -> 2 -> 3 -> 4 -> 5 -> 6
// 2 -> 1 -> 4 -> 3 -> 6 -> 5
ListNode prev = dummyHead;
ListNode node1 = head;
ListNode node2 = head.next;
ListNode next;
while (node1 != null && node2 != null) {
next = node2.next;
node2.next = node1;
node1.next = next;
prev.next = node2;
prev = node1;
node1 = next;
if (node1 != null) node2 = node1.next;
}
return dummyHead.next;
}
public ListNode swapPairs(ListNode node) {
if (node == null || node.next == null) return node;
ListNode node1 = node;
ListNode node2 = node.next;
ListNode res = swapPairs(node2.next);
node2.next = node1;
node1.next = res;
return node2;
}
5、删除链表的倒数第 N 个节点
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummyHead = new ListNode(-1, head);
ListNode p1 = dummyHead;
ListNode p2 = dummyHead;
// 让 p2 向后移动 n + 1 次
for (int i = 0; i < n + 1; i++) p2 = p2.next;
while (p2 != null) {
p1 = p1.next;
p2 = p2.next;
}
p1.next = p1.next.next;
return dummyHead.next;
}
6、链表相交
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode h1 = headA;
ListNode h2 = headB;
while (h1 != h2) {
h1 = h1 != null ? h1.next : headB;
h2 = h2 != null ? h2.next : headA;
}
return h1;
}
7、环形链表 II
慢指针 slow 每次走 1 步
快指针 fast 每次走 2 步
f = 2 * s(快指针每次 2 步,路程是慢指针的 2 倍)
f = s + nb(相遇时,快指针比慢指针多走了 n 圈)
推出:s = nb
从 head 节点走到入环点需要走:a + nb, 而 slow 已经走了 nb,那么 slow 再走 a 步就是入环点了
如何知道 slow 刚好走了 a 步:fast 从 head 开始,和 slow 指针一起走,相遇时刚好就是 a 步
public ListNode detectCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (true) {
if (fast == null || fast.next == null) return null; // 无环
slow = slow.next;
fast = fast.next.next;
if (slow == fast) break;
}
fast = head;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
本文来自博客园,作者:lidongdongdong~,转载请注明原文链接:https://www.cnblogs.com/lidong422339/p/17440643.html