https://oj.leetcode.com/tag/linked-list/
#1 分与合
分的办法:#1 奇偶分(不容易错) #2 快慢中分 #3根据长度中分 复杂度与快慢中分一模一样
interface Divider {
public ListNode divide(ListNode head);
}
// 奇偶中分
class EvenOddDivider implements Divider {
public ListNode divide(ListNode head) {
ListNode evnHead = head;
ListNode oddHead = head.next;
ListNode evnTail = evnHead;
ListNode oddTail = oddHead;
ListNode tail = oddHead.next;
int count = 2;
while (tail != null) {
if (count++ % 2 == 0) {
evnTail.next = tail;
evnTail = tail;
} else {
oddTail.next = tail;
oddTail = tail;
}
tail = tail.next;
}
evnTail.next = null;
oddTail.next = null;
return oddHead;
}
}
// 长度中分
class LengthDivider implements Divider {
// 小心没有分成两份 造成死循环
public ListNode divide(ListNode head) {
int len = length(head);
int mid = len / 2;
for (int i = 0; i < mid - 1; i++) { //如果i=0 当len==2时 没有分成两段 造成死循环
head = head.next;
}
ListNode result = head.next;
head.next = null;
return result;
}
private int length(ListNode head) {
int length = 0;
while(head != null) {
length++;
head = head.next;
}
return length;
}
}
// 快慢中分
class SlowFastDivider implements Divider {
// 小心没有分成两份 造成死循环
public ListNode divide(ListNode head) {
ListNode slow = head;
ListNode fast = head.next; // 如果不降fast指向head.next,那么没有分成两段 造成死循环
while(fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
ListNode result = slow.next;
slow.next = null;
return result;
}
}
class SlowFastDivider2 implements Divider {
public ListNode divide(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while(fast != null) {
fast = fast.next;
if (fast != null) {
fast = fast.next;
if (fast != null) {
slow = slow.next;
}
}
}
ListNode result = slow.next;
slow.next = null;
return result;
}
}
合的办法:#1 有序合 #2拉锁合
https://oj.leetcode.com/problems/sort-list/ (随意分,递归,有序合)
A4:https://oj.leetcode.com/problems/merge-two-sorted-lists/ (有序合)
C23: https://oj.leetcode.com/problems/convert-sorted-list-to-binary-search-tree/ (快慢中分)
E2:https://oj.leetcode.com/problems/swap-nodes-in-pairs/ (奇偶分,拉锁合)
E7:https://oj.leetcode.com/problems/reorder-list/ (快慢中分,逆转,拉链合)
E12:https://oj.leetcode.com/problems/copy-list-with-random-pointer/ (clone到一起,连接random,然后分开。不需要使用map)
#2 逆转
public ListNode reverse(ListNode head) {
ListNode fake = new ListNode(0);
while(head != null) {
ListNode next = head.next;
head.next = fake.next;
fake.next = head;
head = next;
}
return fake.next;
}
// 返回第k个节点 找不到返回null 第一个是head
private ListNode getKNode(ListNode head, int k) {
if(k <= 0) return null;
for(int i = 0; i < k - 1 && head != null; i++) {
head = head.next;
}
return head;
}
E3:https://oj.leetcode.com/problems/reverse-nodes-in-k-group/ (分段逆转 用了getK)
E5:https://oj.leetcode.com/problems/reverse-linked-list-ii/ (分三段 逆转中段 用了getK)
E7:https://oj.leetcode.com/problems/reorder-list/ (快慢中分,逆转,拉链合)
#3 快慢指针
找环,找中点,中分链表
C23: https://oj.leetcode.com/problems/convert-sorted-list-to-binary-search-tree/ (快慢分)
E4:https://oj.leetcode.com/problems/remove-nth-node-from-end-of-list/
E6:https://oj.leetcode.com/problems/rotate-list/
E9:https://oj.leetcode.com/problems/linked-list-cycle/ (重)
https://oj.leetcode.com/problems/linked-list-cycle-ii/ (可以转成E10 比较省事)
E10:https://oj.leetcode.com/problems/intersection-of-two-linked-lists/
#4 去重
E1:https://oj.leetcode.com/problems/remove-duplicates-from-sorted-list/ (同一链表,cur跟next比较,要不要next)
https://oj.leetcode.com/problems/remove-duplicates-from-sorted-list-ii/ (创建新链表。cur跟pre没冲突 cur跟next没冲突 cur往新链表放)
#5 其它
E11:https://oj.leetcode.com/problems/add-two-numbers/ (递归)
#6 排序相关
https://oj.leetcode.com/problems/sort-list/
A2:https://oj.leetcode.com/problems/partition-list/
A4:https://oj.leetcode.com/problems/merge-two-sorted-lists/
A4-B:https://oj.leetcode.com/problems/merge-k-sorted-lists/
E8:https://oj.leetcode.com/problems/insertion-sort-list/
# 7二叉树相关C23: https://oj.leetcode.com/problems/convert-sorted-list-to-binary-search-tree/ (快慢中分)(重)
C24: https://oj.leetcode.com/problems/flatten-binary-tree-to-linked-list/ (后序 先右后左)