📑 题目:82. 删除排序链表中的重复元素 II

🚀 本题 LeetCode 传送门

题目大意

删除链表中重复的结点,只要是有重复过的结点,全部删除。

解题思路

按照题意做即可。

代码

  1. package leetcode
  2. /**
  3. * Definition for singly-linked list.
  4. * type ListNode struct {
  5. * Val int
  6. * Next *ListNode
  7. * }
  8. */
  9. // 解法一
  10. func deleteDuplicates1(head *ListNode) *ListNode {
  11. if head == nil {
  12. return nil
  13. }
  14. if head.Next == nil {
  15. return head
  16. }
  17. newHead := &ListNode{Next: head, Val: -999999}
  18. cur := newHead
  19. last := newHead
  20. front := head
  21. for front.Next != nil {
  22. if front.Val == cur.Val {
  23. // fmt.Printf(""相同节点front = %v | cur = %v | last = %v
  24. "", front.Val, cur.Val, last.Val)
  25. front = front.Next
  26. continue
  27. } else {
  28. if cur.Next != front {
  29. // fmt.Printf(""删除重复节点front = %v | cur = %v | last = %v
  30. "", front.Val, cur.Val, last.Val)
  31. last.Next = front
  32. if front.Next != nil && front.Next.Val != front.Val {
  33. last = front
  34. }
  35. cur = front
  36. front = front.Next
  37. } else {
  38. // fmt.Printf(""常规循环前front = %v | cur = %v | last = %v
  39. "", front.Val, cur.Val, last.Val)
  40. last = cur
  41. cur = cur.Next
  42. front = front.Next
  43. // fmt.Printf(""常规循环后front = %v | cur = %v | last = %v
  44. "", front.Val, cur.Val, last.Val)
  45. }
  46. }
  47. }
  48. if front.Val == cur.Val {
  49. // fmt.Printf(""相同节点front = %v | cur = %v | last = %v
  50. "", front.Val, cur.Val, last.Val)
  51. last.Next = nil
  52. } else {
  53. if cur.Next != front {
  54. last.Next = front
  55. }
  56. }
  57. return newHead.Next
  58. }
  59. // 解法二
  60. func deleteDuplicates2(head *ListNode) *ListNode {
  61. if head == nil {
  62. return nil
  63. }
  64. if head.Next != nil && head.Val == head.Next.Val {
  65. for head.Next != nil && head.Val == head.Next.Val {
  66. head = head.Next
  67. }
  68. return deleteDuplicates(head.Next)
  69. }
  70. head.Next = deleteDuplicates(head.Next)
  71. return head
  72. }
  73. func deleteDuplicates(head *ListNode) *ListNode {
  74. cur := head
  75. if head == nil {
  76. return nil
  77. }
  78. if head.Next == nil {
  79. return head
  80. }
  81. for cur.Next != nil {
  82. if cur.Next.Val == cur.Val {
  83. cur.Next = cur.Next.Next
  84. } else {
  85. cur = cur.Next
  86. }
  87. }
  88. return head
  89. }
  90. // 解法三 双循环简单解法 O(n*m)
  91. func deleteDuplicates3(head *ListNode) *ListNode {
  92. if head == nil {
  93. return head
  94. }
  95. nilNode := &ListNode{Val: 0, Next: head}
  96. head = nilNode
  97. lastVal := 0
  98. for head.Next != nil && head.Next.Next != nil {
  99. if head.Next.Val == head.Next.Next.Val {
  100. lastVal = head.Next.Val
  101. for head.Next != nil && lastVal == head.Next.Val {
  102. head.Next = head.Next.Next
  103. }
  104. } else {
  105. head = head.Next
  106. }
  107. }
  108. return nilNode.Next
  109. }
  110. // 解法四 双指针+删除标志位,单循环解法 O(n)
  111. func deleteDuplicates4(head *ListNode) *ListNode {
  112. if head == nil || head.Next == nil {
  113. return head
  114. }
  115. nilNode := &ListNode{Val: 0, Next: head}
  116. // 上次遍历有删除操作的标志位
  117. lastIsDel := false
  118. // 虚拟空结点
  119. head = nilNode
  120. // 前后指针用于判断
  121. pre, back := head.Next, head.Next.Next
  122. // 每次只删除前面的一个重复的元素,留一个用于下次遍历判重
  123. // pre, back 指针的更新位置和值比较重要和巧妙
  124. for head.Next != nil && head.Next.Next != nil {
  125. if pre.Val != back.Val && lastIsDel {
  126. head.Next = head.Next.Next
  127. pre, back = head.Next, head.Next.Next
  128. lastIsDel = false
  129. continue
  130. }
  131. if pre.Val == back.Val {
  132. head.Next = head.Next.Next
  133. pre, back = head.Next, head.Next.Next
  134. lastIsDel = true
  135. } else {
  136. head = head.Next
  137. pre, back = head.Next, head.Next.Next
  138. lastIsDel = false
  139. }
  140. }
  141. // 处理 [1,1] 这种删除还剩一个的情况
  142. if lastIsDel && head.Next != nil {
  143. head.Next = nil
  144. }
  145. return nilNode.Next
  146. }