Skip to content

Commit cbb0999

Browse files
author
anduo
committed
linked list
1 parent 42e6378 commit cbb0999

11 files changed

+513
-0
lines changed

imgs/subsets.png

104 KB
Loading

readme.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,3 +277,23 @@ doc中有好几份文档,比较经典,可以参考。
277277
- substring with concatenation of all words
278278
- letter combination of a phone number
279279

280+
## chapter05 linked list
281+
282+
需要掌握的技能
283+
- insert a node in sorted list
284+
- **remove a node from linked list**
285+
- **reverse a linked list**
286+
- merge two linked list
287+
- find the middle of a linked list
288+
289+
**Dummy Node**
290+
1. remove duplicates from sorted list i,ii
291+
2. merge two sorted lists
292+
3. partition list
293+
4. reverse linked list ii
294+
295+
**Two Pointer **
296+
297+
## chapter06 dynamic programming
298+
299+
DP的本质就是 **记忆化搜索**
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package ninechapter.ch05_linked_list;
2+
3+
import entity.ListNode;
4+
5+
/**
6+
* Created by anduo on 17-3-14.
7+
*/
8+
public class Question01SortList {
9+
public ListNode sortList(ListNode head) {
10+
// merge sort
11+
if (head == null || head.next == null) {
12+
return head;
13+
}
14+
ListNode mid = findMiddle(head);
15+
16+
ListNode right = sortList(mid.next);
17+
mid.next = null;
18+
ListNode left = sortList(head);
19+
return merge(left, right);
20+
}
21+
22+
private ListNode findMiddle(ListNode head) {
23+
ListNode slow = head, fast = head.next;
24+
while (fast != null && fast.next != null) {
25+
fast = fast.next.next;
26+
slow = slow.next;
27+
}
28+
return slow;
29+
}
30+
31+
private ListNode merge(ListNode head1, ListNode head2) {
32+
ListNode dummy = new ListNode(0);
33+
ListNode tail = dummy;
34+
while (head1 != null && head2 != null) {
35+
if (head1.val < head2.val) {
36+
tail.next = head1;
37+
head1 = head1.next;
38+
} else {
39+
tail.next = head2;
40+
head2 = head2.next;
41+
}
42+
tail = tail.next;
43+
}
44+
if (head1 != null) {
45+
tail.next = head1;
46+
} else {
47+
tail.next = head2;
48+
}
49+
50+
return dummy.next;
51+
}
52+
53+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package ninechapter.ch05_linked_list;
2+
3+
import entity.ListNode;
4+
5+
// https://leetcode.com/problems/reverse-linked-list-ii
6+
// Reverse a linked list from position m to n. Do it in-place and in one-pass.
7+
// For example:
8+
// Given 1->2->3->4->5->NULL, m = 2 and n = 4,
9+
// return 1->4->3->2->5->NULL.
10+
11+
/**
12+
* Created by anduo on 17-3-14.
13+
*/
14+
public class Question02ReverseLinkedListII {
15+
public ListNode reverseBetween(ListNode head, int m, int n) {
16+
if (head == null || m >= n) {
17+
return head;
18+
}
19+
20+
ListNode dummy = new ListNode(0);
21+
22+
// move to m'th node
23+
for (int i = 0; i < m; i++) {
24+
if (head == null) {
25+
return null;
26+
}
27+
head = head.next;
28+
}
29+
30+
ListNode premNode = head;
31+
ListNode mNode = head.next;
32+
ListNode nNode = mNode, postnNode = mNode.next;
33+
for (int i = m; i < n; i++) {
34+
if (postnNode == null) {
35+
return null;
36+
}
37+
ListNode temp = postnNode.next;
38+
postnNode.next = nNode;
39+
nNode = postnNode;
40+
postnNode = temp;
41+
}
42+
mNode.next = postnNode;
43+
premNode.next = nNode;
44+
45+
return dummy.next;
46+
}
47+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package ninechapter.ch05_linked_list;
2+
3+
// https://leetcode.com/problems/reorder-list/
4+
//Given a singly linked list
5+
// L: L0→L1→…→Ln-1→Ln,
6+
// reorder it to:
7+
// L0→Ln→L1→Ln-1→L2→Ln-2→…
8+
//
9+
// You must do this in-place without altering the nodes' values.
10+
//
11+
// For example,
12+
// Given {1,2,3,4}, reorder it to {1,4,2,3}.
13+
14+
import entity.ListNode;
15+
16+
/**
17+
* Created by anduo on 17-3-14.
18+
*/
19+
public class Question03ReorderList {
20+
21+
private ListNode reverse(ListNode head) {
22+
ListNode newHead = null;
23+
while (head != null) {
24+
ListNode temp = head.next;
25+
head.next = newHead;
26+
newHead = head;
27+
head = temp;
28+
}
29+
return newHead;
30+
}
31+
32+
private void merge(ListNode head1, ListNode head2) {
33+
int index = 0;
34+
ListNode dummy = new ListNode(0);
35+
while (head1 != null && head2 != null) {
36+
if (index % 2 == 0) {
37+
dummy.next = head1;
38+
head1 = head1.next;
39+
} else {
40+
dummy.next = head2;
41+
head2 = head2.next;
42+
}
43+
dummy = dummy.next;
44+
index++;
45+
}
46+
if (head1 != null) {
47+
dummy.next = head1;
48+
} else {
49+
dummy.next = head2;
50+
}
51+
}
52+
53+
private ListNode findMiddle(ListNode head) {
54+
ListNode slow = head, fast = head.next;
55+
while (fast != null && fast.next != null) {
56+
fast = fast.next.next;
57+
slow = slow.next;
58+
}
59+
return slow;
60+
}
61+
62+
public void reorderList(ListNode head) {
63+
if (head == null || head.next == null) {
64+
return;
65+
}
66+
67+
ListNode mid = findMiddle(head);// 找到中间节点
68+
ListNode tail = reverse(mid.next);// 翻转后半部分链表
69+
mid.next = null;// 断开前半部分的链表
70+
71+
merge(head, tail); // 合并
72+
}
73+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package ninechapter.ch05_linked_list;
2+
3+
// https://leetcode.com/problems/partition-list
4+
// Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.
5+
6+
// You should preserve the original relative order of the nodes in each of the two partitions.
7+
//
8+
// For example,
9+
// Given 1->4->3->2->5->2 and x = 3,
10+
// return 1->2->2->4->3->5.
11+
12+
import entity.ListNode;
13+
14+
/**
15+
* Created by anduo on 17-3-14.
16+
*/
17+
public class Question04PartitionList {
18+
19+
public ListNode partition(ListNode head, int x) {
20+
if (head == null) {
21+
return head;
22+
}
23+
24+
ListNode leftDummy = new ListNode(0);
25+
ListNode rightDummy = new ListNode(0);
26+
27+
ListNode left = leftDummy, right = rightDummy;
28+
while (head != null) {
29+
if (head.val < x) {
30+
left.next = head;
31+
left = left.next;
32+
}else {
33+
right.next = head;
34+
right = right.next;
35+
}
36+
head = head.next;
37+
}
38+
39+
right.next = null;
40+
left.next = rightDummy.next;
41+
return leftDummy.next;
42+
}
43+
44+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package ninechapter.ch05_linked_list;
2+
3+
import entity.ListNode;
4+
// https://leetcode.com/problems/linked-list-cycle
5+
// 判断一个链表是不是有环
6+
// 快慢指针就可以了
7+
8+
/**
9+
* Created by anduo on 17-3-14.
10+
*/
11+
public class Question05LinkedListCycle {
12+
13+
public boolean hasCycle(ListNode head) {
14+
if (head == null || head.next == null) {
15+
return false;
16+
}
17+
18+
ListNode slow = head, fast = head.next;
19+
do {
20+
if (fast.next == null || fast.next.next == null) {
21+
return false;
22+
}
23+
fast = fast.next.next;
24+
slow = slow.next;
25+
} while (slow != fast);
26+
27+
return true;
28+
}
29+
30+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package ninechapter.ch05_linked_list;
2+
3+
import entity.ListNode;
4+
// https://leetcode.com/problems/linked-list-cycle
5+
// 判断一个链表是不是有环
6+
// 快慢指针就可以了
7+
8+
/**
9+
* Created by anduo on 17-3-14.
10+
*/
11+
public class Question06LinkedListCycleII {
12+
13+
public ListNode detectCycle(ListNode head) {
14+
if (head == null || head.next == null) {
15+
return null;
16+
}
17+
18+
ListNode fast, slow;
19+
fast = head.next;
20+
slow = head;
21+
while (fast != slow) {// fast追上slow
22+
if (fast == null || fast.next == null) {
23+
return null;
24+
}
25+
fast = fast.next.next;
26+
slow = slow.next;
27+
}
28+
29+
while (head != slow.next) {
30+
// 另一个指针开始从头开始走,slow和head相遇的是否就是环的起点
31+
head = head.next;
32+
slow = slow.next;
33+
}
34+
return head;
35+
}
36+
37+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package ninechapter.ch05_linked_list;
2+
3+
// https://leetcode.com/problems/copy-list-with-random-pointer/#/description
4+
// A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
5+
//
6+
// Return a deep copy of the list.
7+
8+
import entity.RandomListNode;
9+
10+
/**
11+
* Created by anduo on 17-3-14.
12+
*/
13+
///**
14+
// * Definition for singly-linked list with a random pointer.
15+
// * class RandomListNode {
16+
// * int label;
17+
// * RandomListNode next, random;
18+
// * RandomListNode(int x) { this.label = x; }
19+
// * };
20+
// */
21+
22+
/**
23+
* 第一遍扫的时候巧妙运用next指针, 开始数组是1->2->3->4 。
24+
* 然后扫描过程中 先建立copy节点 1->1`->2->2`->3->3`->4->4`,
25+
* 然后第二遍copy的时候去建立边的copy, 拆分节点, 一边扫描一边拆成两个链表,这里用到两个dummy node。
26+
* 第一个链表变回 1->2->3 , 然后第二变成 1`->2`->3`
27+
*/
28+
public class Question07CopyListWithRandomPointer {
29+
30+
31+
private void copyNext(RandomListNode head) {
32+
while (head != null) {
33+
RandomListNode newNode = new RandomListNode(head.label);
34+
newNode.random = head.random;
35+
newNode.next = head.next;
36+
head.next = newNode;
37+
head = head.next.next;
38+
}
39+
}
40+
41+
private void copyRandom(RandomListNode head) {
42+
while (head != null) {
43+
if (head.next.random != null) {
44+
head.next.random = head.random.next;
45+
}
46+
head = head.next.next;
47+
}
48+
}
49+
50+
private RandomListNode splitList(RandomListNode head) {
51+
RandomListNode newHead = head.next;
52+
while (head != null) {
53+
RandomListNode temp = head.next;
54+
head.next = temp.next;
55+
head = head.next;
56+
if (temp.next != null) {
57+
temp.next = temp.next.next;
58+
}
59+
}
60+
return newHead;
61+
}
62+
63+
public RandomListNode copyRandomList(RandomListNode head) {
64+
if (head == null) {
65+
return null;
66+
}
67+
copyNext(head);
68+
copyRandom(head);
69+
return splitList(head);
70+
}
71+
}

0 commit comments

Comments
 (0)