数据结构与算法-链表
- 链表经典题目
- 25. K 个一组翻转链表 ❤️
- 92. 反转链表 II
- 23. 合并 K 个升序链表
- 143. 重排链表 ❤️
- 160. 相交链表
- 82. 删除排序链表中的重复元素 II
- 148. 排序链表
- 234. 回文链表
- 83. 删除排序链表中的重复元素
- 24. 两两交换链表中的节点 ❤️
- 138. 随机链表的复制
- 61. 旋转链表
- 补充题 1. 排序奇升偶降链表
- 86. 分隔链表
- 109. 有序链表转换二叉搜索树
- 1171. 从链表中删去总和值为零的连续节点
- 147. 对链表进行插入排序
- 369. 给单链表加一
- 1669. 合并两个链表
- 面试题 02.01. 移除重复节点
- 1367. 二叉树中的链表
- 1019. 链表中的下一个更大节点
- 725. 分隔链表
- 146. LRU 缓存
链表经典题目
25. K 个一组翻转链表 ❤️
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
func reverseKGroup(head *ListNode, k int) *ListNode {
if head == nil || k == 1 {
return head
}
tail := head
for i := 0; i < k; i++ {
if tail == nil {
return head
}
tail = tail.Next
}
newHead := reverse(head, tail)
head.Next = reverseKGroup(tail, k)
return newHead
}
func reverse(head *ListNode, tail *ListNode) *ListNode {
var pre *ListNode
cur := head
for cur != tail {
next := cur.Next
cur.Next = pre
pre = cur
cur = next
}
return pre
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
func reverseKGroup(head *ListNode, k int) *ListNode {
// 计算链表长度
length := 0
cur := head
for cur != nil {
length++
cur = cur.Next
}
dummy := &ListNode{Next: head}
preGroupEnd := dummy
for length >= k {
cur := preGroupEnd.Next
nextGroupStart := cur
var pre *ListNode
for i := 0; i < k; i++ {
next := cur.Next
cur.Next = pre
pre = cur
cur = next
}
preGroupEnd.Next = pre
nextGroupStart.Next = cur
preGroupEnd = nextGroupStart
length = length - k
}
return dummy.Next
}
92. 反转链表 II
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func reverseBetween(head *ListNode, left int, right int) *ListNode {
if head == nil || head.Next == nil || left == right {
return head
}
dummy := &ListNode{Next: head}
slow := dummy
for i := 1; i < left; i++ {
slow = slow.Next
}
cur := slow.Next
var pre *ListNode
for i := left; i <= right; i++ {
next := cur.Next
cur.Next = pre
pre = cur
cur = next
}
slow.Next.Next = cur
slow.Next = pre
return dummy.Next
}
23. 合并 K 个升序链表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
func mergeKLists(lists []*ListNode) *ListNode {
if len(lists) == 0 {
return nil
} else if len(lists) == 1 {
return lists[0]
}
mid := len(lists) / 2
l1 := mergeKLists(lists[:mid])
l2 := mergeKLists(lists[mid:])
return mergeTwoLists(l1, l2)
}
func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
if l1 == nil {
return l2
} else if l2 == nil {
return l1
}
dummy := &ListNode{}
cur := dummy
for l1 != nil && l2 != nil {
if l1.Val < l2.Val {
cur.Next = l1
l1 = l1.Next
} else {
cur.Next = l2
l2 = l2.Next
}
cur = cur.Next
}
if l1 != nil {
cur.Next = l1
} else {
cur.Next = l2
}
return dummy.Next
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// 合并 K 个升序链表
func mergeKLists(lists []*ListNode) *ListNode {
if len(lists) == 0 {
return nil
}
// 从第一个链表开始
mergedList := lists[0]
// 依次合并每个链表
for i := 1; i < len(lists); i++ {
mergedList = mergeTwoLists(mergedList, lists[i])
}
return mergedList
}
// 合并两个有序链表
func mergeTwoLists(l1, l2 *ListNode) *ListNode {
dummy := &ListNode{}
cur := dummy
for l1 != nil && l2 != nil {
if l1.Val < l2.Val {
cur.Next = l1
l1 = l1.Next
} else {
cur.Next = l2
l2 = l2.Next
}
cur = cur.Next
}
if l1 != nil {
cur.Next = l1
} else {
cur.Next = l2
}
return dummy.Next
}
143. 重排链表 ❤️
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
func reorderList(head *ListNode) {
if head == nil || head.Next == nil {
return
}
slow, fast := head, head
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
}
var pre *ListNode
cur := slow.Next
for cur != nil {
next := cur.Next
cur.Next = pre
pre = cur
cur = next
}
slow.Next = nil
p1, p2 := head, pre
for p2 != nil {
next1, next2 := p1.Next, p2.Next
p1.Next = p2
p2.Next = next1
p1 = next1
p2 = next2
}
}
160. 相交链表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func getIntersectionNode(headA, headB *ListNode) *ListNode {
a, b := headA, headB
for a != b {
if a != nil {
a = a.Next
} else {
a = headB
}
if b != nil {
b = b.Next
} else {
b = headA
}
}
return a
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
func getIntersectionNode(headA, headB *ListNode) *ListNode {
// 计算链表 A 的长度
lengthA := 0
for cur := headA; cur != nil; cur = cur.Next {
lengthA++
}
// 计算链表 B 的长度
lengthB := 0
for cur := headB; cur != nil; cur = cur.Next {
lengthB++
}
a, b := headA, headB
// 让较长的链表先走几步
for lengthA > lengthB {
a = a.Next
lengthA--
}
for lengthB > lengthA {
b = b.Next
lengthB--
}
// 同时遍历两个链表,找到相交节点
for a != b {
a = a.Next
b = b.Next
}
return a
}
82. 删除排序链表中的重复元素 II
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
func deleteDuplicates(head *ListNode) *ListNode {
dummy := &ListNode{Next: head}
pre, cur := dummy, head
for cur != nil {
isDuplicate := false
for cur.Next != nil && cur.Next.Val == cur.Val {
cur = cur.Next
isDuplicate = true
}
if isDuplicate {
pre.Next = cur.Next
} else {
pre = cur
}
cur = cur.Next
}
return dummy.Next
}
148. 排序链表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
func sortList(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
dummy := &ListNode{}
dummy.Next = head
slow, fast := dummy, dummy
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
}
rightHead := slow.Next
slow.Next = nil
l1 := sortList(head)
l2 := sortList(rightHead)
return mergeTwoLists(l1, l2)
}
func mergeTwoLists(l1, l2 *ListNode) *ListNode {
if l1 == nil {
return l2
} else if l2 == nil {
return l1
}
dummy := &ListNode{}
cur := dummy
for l1 != nil && l2 != nil {
if l1.Val < l2.Val {
cur.Next = l1
l1 = l1.Next
} else {
cur.Next = l2
l2 = l2.Next
}
cur = cur.Next
}
if l1 != nil {
cur.Next = l1
} else if l2 != nil {
cur.Next = l2
}
return dummy.Next
}
234. 回文链表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
func isPalindrome(head *ListNode) bool {
if head == nil || head.Next == nil {
return true
}
// 使用快慢指针找到链表的中间节点
slow, fast := head, head
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
}
// 反转链表的后半部分
var pre *ListNode
cur := slow
for cur != nil {
next := cur.Next
cur.Next = pre
pre = cur
cur = next
}
// 比较链表的前半部分和反转后的后半部分是否相同
left, right := head, pre
for right != nil {
if left.Val != right.Val {
return false
}
left = left.Next
right = right.Next
}
return true
}
83. 删除排序链表中的重复元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func deleteDuplicates(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
cur := head
for cur.Next != nil {
if cur.Next.Val == cur.Val {
cur.Next = cur.Next.Next
} else {
cur = cur.Next
}
}
return head
}
24. 两两交换链表中的节点 ❤️
1
2
3
4
5
6
7
8
9
10
11
12
13
func swapPairs(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
first := head
second := head.Next
first.Next = swapPairs(second.Next)
second.Next = first
return second
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
func swapPairs(head *ListNode) *ListNode {
dummy := &ListNode{Next: head}
pre := dummy
for pre.Next != nil && pre.Next.Next != nil {
first := pre.Next
second := pre.Next.Next
first.Next = second.Next
second.Next = first
pre.Next = second
pre = first
}
return dummy.Next
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func swapPairs(head *ListNode) *ListNode {
dummy := &ListNode{Next: head}
pre := dummy
cur := head
for cur != nil && cur.Next != nil {
first := cur
second := cur.Next
first.Next = second.Next
second.Next = first
pre.Next = second
pre = first
cur = first.Next
}
return dummy.Next
}
138. 随机链表的复制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
func copyRandomList(head *Node) *Node {
if head == nil {
return nil
}
// 第一步:在每个节点后面插入一个新节点
cur := head
for cur != nil {
newNode := &Node{Val: cur.Val, Next: cur.Next}
cur.Next = newNode
cur = newNode.Next
}
// 第二步:更新新节点的随机指针
cur = head
for cur != nil {
if cur.Random != nil {
cur.Next.Random = cur.Random.Next
}
cur = cur.Next.Next
}
// 第三步:拆分链表
cur = head
newHead := head.Next
for cur != nil {
newNode := cur.Next
cur.Next = newNode.Next
if newNode.Next != nil {
newNode.Next = newNode.Next.Next
}
cur = cur.Next
}
return newHead
}
61. 旋转链表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
func rotateRight(head *ListNode, k int) *ListNode {
if head == nil || head.Next == nil || k == 0 {
return head
}
length := 1
cur := head
for cur.Next != nil {
length++
cur = cur.Next
}
k = k % length
if k == 0 {
return head
}
cur.Next = head
for i := 0; i < length-k; i++ {
cur = cur.Next
}
newHead := cur.Next
cur.Next = nil
return newHead
}
补充题 1. 排序奇升偶降链表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// 排序奇升偶降链表
func sortOddEvenList(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
// 拆分奇偶链表
odd, even := head, head.Next
oddHead, evenHead := odd, even
for even != nil && even.Next != nil {
odd.Next = odd.Next.Next
odd = odd.Next
even.Next = even.Next.Next
even = even.Next
}
odd.Next = nil // 非常重要
// 反转偶数链表
var pre *ListNode
cur := evenHead
for cur != nil {
next := cur.Next
cur.Next = pre
pre = cur
cur = next
}
evenHead = pre
// 合并两个链表
dummy := &ListNode{}
cur = dummy
l1, l2 := oddHead, evenHead
for l1 != nil && l2 != nil {
if l1.Val < l2.Val {
cur.Next = l1
l1 = l1.Next
} else {
cur.Next = l2
l2 = l2.Next
}
cur = cur.Next
}
if l1 != nil {
cur.Next = l1
} else if l2 != nil {
cur.Next = l2
}
return dummy.Next
}
86. 分隔链表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
func partition(head *ListNode, x int) *ListNode {
if head == nil || head.Next == nil {
return head
}
leftHead := &ListNode{}
rightHead := &ListNode{}
left := leftHead
right := rightHead
cur := head
for cur != nil {
if cur.Val < x {
left.Next = cur
left = left.Next
} else {
right.Next = cur
right = right.Next
}
cur = cur.Next
}
right.Next = nil // 特别注意:此处一定要断开,防止循环引用。
left.Next = rightHead.Next
return leftHead.Next
}
109. 有序链表转换二叉搜索树
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
func findMiddle(head *ListNode) *ListNode {
var pre *ListNode
slow, fast := head, head
for fast != nil && fast.Next != nil {
pre = slow
slow = slow.Next
fast = fast.Next.Next
}
if pre != nil {
pre.Next = nil // 切断链表
}
return slow
}
func sortedListToBST(head *ListNode) *TreeNode {
if head == nil {
return nil
}
mid := findMiddle(head)
root := &TreeNode{Val: mid.Val}
if head == mid {
return root
}
root.Left = sortedListToBST(head)
root.Right = sortedListToBST(mid.Next)
return root
}
1171. 从链表中删去总和值为零的连续节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func removeZeroSumSublists(head *ListNode) *ListNode {
dummy := &ListNode{Next: head}
prefixSum := 0
sumMap := make(map[int]*ListNode)
sumMap[0] = dummy
// 第一次遍历,记录前缀和及其对应的节点
for cur := dummy; cur != nil; cur = cur.Next {
prefixSum += cur.Val
sumMap[prefixSum] = cur
}
// 第二次遍历,删除前缀和相同的节点之间的节点
prefixSum = 0
for cur := dummy; cur != nil; cur = cur.Next {
prefixSum += cur.Val
cur.Next = sumMap[prefixSum].Next
}
return dummy.Next
}
147. 对链表进行插入排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
func insertionSortList(head *ListNode) *ListNode {
dummy := &ListNode{}
cur := head
for cur != nil {
// 保存下一个节点
next := cur.Next
// 找到插入位置
pre := dummy
for pre.Next != nil && pre.Next.Val < cur.Val {
pre = pre.Next
}
// 插入节点
cur.Next = pre.Next
pre.Next = cur
// 处理下一个节点
cur = next
}
return dummy.Next
}
369. 给单链表加一
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
func plusOne(head *ListNode) *ListNode {
var stack []int
for head != nil {
stack = append(stack, head.Val)
head = head.Next
}
carry := 1
var pre *ListNode
// 依次从栈顶取出节点值进行加一
for len(stack) > 0 || carry > 0 {
sum := carry
if len(stack) > 0 {
sum += stack[len(stack)-1]
stack = stack[:len(stack)-1]
}
// 处理进位
carry = sum / 10
sum = sum % 10
// 创建新节点并插入到链表头部
cur := &ListNode{Val: sum}
cur.Next = pre
pre = cur
}
return pre
}
1669. 合并两个链表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func mergeInBetween(list1 *ListNode, a int, b int, list2 *ListNode) *ListNode {
dummy := &ListNode{Next: list1}
preA := dummy
preB := dummy
for i := 0; i < a; i++ {
preA = preA.Next
}
for i := 0; i < b+2; i++ {
preB = preB.Next
}
preA.Next = list2
tail := list2
for tail.Next != nil {
tail = tail.Next
}
tail.Next = preB
return list1
}
面试题 02.01. 移除重复节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func removeDuplicateNodes(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
seem := make(map[int]bool)
dummy := &ListNode{Next: head}
pre := dummy
cur := head
for cur != nil {
if seem[cur.Val] {
pre.Next = cur.Next
} else {
pre = cur
}
seem[cur.Val] = true
cur = cur.Next
}
return dummy.Next
}
1367. 二叉树中的链表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func isSubPath(head *ListNode, root *TreeNode) bool {
var dfs func(node *TreeNode, curr *ListNode) bool
dfs = func(node *TreeNode, curr *ListNode) bool {
if curr == nil {
return true // 链表遍历完,返回 true
}
if node == nil || node.Val != curr.Val {
return false // 当前节点为空或值不匹配,返回 false
}
// 继续遍历左右子树
return dfs(node.Left, curr.Next) || dfs(node.Right, curr.Next)
}
// 从根节点开始遍历
if root == nil {
return false
}
return dfs(root, head) || isSubPath(head, root.Left) || isSubPath(head, root.Right)
}
1019. 链表中的下一个更大节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func nextLargerNodes(head *ListNode) []int {
var nums []int
cur := head
for cur != nil {
nums = append(nums, cur.Val)
cur = cur.Next
}
res := make([]int, len(nums))
var stack []int
for i, num := range nums {
for len(stack) > 0 && num > nums[stack[len(stack)-1]] {
res[stack[len(stack)-1]] = num
stack = stack[:len(stack)-1]
}
stack = append(stack, i)
}
return res
}
725. 分隔链表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
func splitListToParts(head *ListNode, k int) []*ListNode {
// 计算链表的长度
length := 0
for cur := head; cur != nil; cur = cur.Next {
length++
}
// 计算每个部分的基本长度和额外节点数
partSize := length / k
extraSize := length % k
// 创建结果数组
res := make([]*ListNode, k)
cur := head
for i := 0; i < k; i++ {
res[i] = cur
// 计算当前部分的长度
size := partSize
if i < extraSize {
size++ // 前面部分多一个节点
}
// 遍历当前部分
for j := 0; j < size && cur != nil; j++ {
if j == size-1 {
next := cur.Next
cur.Next = nil // 断开链表
cur = next
} else {
cur = cur.Next
}
}
}
return res
}
146. LRU 缓存
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
type Node struct {
key, value int
pre, next *Node
}
type LRUCache struct {
capacity int
cache map[int]*Node
head, tail *Node
}
func Constructor(capacity int) LRUCache {
head := &Node{}
tail := &Node{}
head.next = tail
tail.pre = head
return LRUCache{
capacity: capacity,
cache: make(map[int]*Node),
head: head,
tail: tail,
}
}
func (this *LRUCache) Get(key int) int {
if node, exists := this.cache[key]; exists {
this.moveToHead(node)
return node.value
}
return -1
}
func (this *LRUCache) Put(key int, value int) {
if node, exists := this.cache[key]; exists {
node.value = value
this.moveToHead(node)
} else {
newNode := &Node{key: key, value: value}
this.cache[key] = newNode
this.addToHead(newNode)
if len(this.cache) > this.capacity {
removed := this.removeTail()
delete(this.cache, removed.key)
}
}
}
func (this *LRUCache) moveToHead(node *Node) {
this.removeNode(node)
this.addToHead(node)
}
func (this *LRUCache) addToHead(node *Node) {
node.pre = this.head
node.next = this.head.next
this.head.next.pre = node
this.head.next = node
}
func (this *LRUCache) removeNode(node *Node) {
node.pre.next = node.next
node.next.pre = node.pre
}
func (this *LRUCache) removeTail() *Node {
node := this.tail.pre
this.removeNode(node)
return node
}
CC BY-NC-SA 4.0
许可协议,转载请注明出处!
本博客所有文章除特别声明外,均采用