-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
/
82. Remove Duplicates from Sorted List II.go
156 lines (144 loc) · 3.48 KB
/
82. Remove Duplicates from Sorted List II.go
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package leetcode
import (
"github.com/halfrost/LeetCode-Go/structures"
)
// ListNode define
type ListNode = structures.ListNode
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func deleteDuplicates1(head *ListNode) *ListNode {
if head == nil {
return nil
}
if head.Next == nil {
return head
}
newHead := &ListNode{Next: head, Val: -999999}
cur := newHead
last := newHead
front := head
for front.Next != nil {
if front.Val == cur.Val {
// fmt.Printf("相同节点front = %v | cur = %v | last = %v\n", front.Val, cur.Val, last.Val)
front = front.Next
continue
} else {
if cur.Next != front {
// fmt.Printf("删除重复节点front = %v | cur = %v | last = %v\n", front.Val, cur.Val, last.Val)
last.Next = front
if front.Next != nil && front.Next.Val != front.Val {
last = front
}
cur = front
front = front.Next
} else {
// fmt.Printf("常规循环前front = %v | cur = %v | last = %v\n", front.Val, cur.Val, last.Val)
last = cur
cur = cur.Next
front = front.Next
// fmt.Printf("常规循环后front = %v | cur = %v | last = %v\n", front.Val, cur.Val, last.Val)
}
}
}
if front.Val == cur.Val {
// fmt.Printf("相同节点front = %v | cur = %v | last = %v\n", front.Val, cur.Val, last.Val)
last.Next = nil
} else {
if cur.Next != front {
last.Next = front
}
}
return newHead.Next
}
func deleteDuplicates2(head *ListNode) *ListNode {
if head == nil {
return nil
}
if head.Next != nil && head.Val == head.Next.Val {
for head.Next != nil && head.Val == head.Next.Val {
head = head.Next
}
return deleteDuplicates(head.Next)
}
head.Next = deleteDuplicates(head.Next)
return head
}
func deleteDuplicates(head *ListNode) *ListNode {
cur := head
if head == nil {
return nil
}
if head.Next == nil {
return head
}
for cur.Next != nil {
if cur.Next.Val == cur.Val {
cur.Next = cur.Next.Next
} else {
cur = cur.Next
}
}
return head
}
// 双循环简单解法 O(n*m)
func deleteDuplicates3(head *ListNode) *ListNode {
if head == nil {
return head
}
nilNode := &ListNode{Val: 0, Next: head}
head = nilNode
lastVal := 0
for head.Next != nil && head.Next.Next != nil {
if head.Next.Val == head.Next.Next.Val {
lastVal = head.Next.Val
for head.Next != nil && lastVal == head.Next.Val {
head.Next = head.Next.Next
}
} else {
head = head.Next
}
}
return nilNode.Next
}
// 双指针+删除标志位,单循环解法 O(n)
func deleteDuplicates4(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
nilNode := &ListNode{Val: 0, Next: head}
// 上次遍历有删除操作的标志位
lastIsDel := false
// 虚拟空结点
head = nilNode
// 前后指针用于判断
pre, back := head.Next, head.Next.Next
// 每次只删除前面的一个重复的元素,留一个用于下次遍历判重
// pre, back 指针的更新位置和值比较重要和巧妙
for head.Next != nil && head.Next.Next != nil {
if pre.Val != back.Val && lastIsDel {
head.Next = head.Next.Next
pre, back = head.Next, head.Next.Next
lastIsDel = false
continue
}
if pre.Val == back.Val {
head.Next = head.Next.Next
pre, back = head.Next, head.Next.Next
lastIsDel = true
} else {
head = head.Next
pre, back = head.Next, head.Next.Next
lastIsDel = false
}
}
// 处理 [1,1] 这种删除还剩一个的情况
if lastIsDel && head.Next != nil {
head.Next = nil
}
return nilNode.Next
}