Remove Duplicates from Sorted List

Question

  1. Given a sorted linked list,
  2. delete all duplicates such that each element appear only once.
  3. Example
  4. Given 1->1->2, return 1->2.
  5. Given 1->1->2->3->3, return 1->2->3.

題解

遍歷之,遇到當前節點和下一節點的值相同時,刪除下一節點,並將當前節點next值指向下一個節點的next, 當前節點首先保持不變,直到相鄰節點的值不等時才移動到下一節點。

Python

  1. # Definition for singly-linked list.
  2. # class ListNode:
  3. # def __init__(self, x):
  4. # self.val = x
  5. # self.next = None
  6. class Solution:
  7. # @param {ListNode} head
  8. # @return {ListNode}
  9. def deleteDuplicates(self, head):
  10. if head is None:
  11. return None
  12. node = head
  13. while node.next is not None:
  14. if node.val == node.next.val:
  15. node.next = node.next.next
  16. else:
  17. node = node.next
  18. return head

C++

  1. /**
  2. * Definition of ListNode
  3. * class ListNode {
  4. * public:
  5. * int val;
  6. * ListNode *next;
  7. * ListNode(int val) {
  8. * this->val = val;
  9. * this->next = NULL;
  10. * }
  11. * }
  12. */
  13. class Solution {
  14. public:
  15. /**
  16. * @param head: The first node of linked list.
  17. * @return: head node
  18. */
  19. ListNode *deleteDuplicates(ListNode *head) {
  20. if (head == NULL) {
  21. return NULL;
  22. }
  23. ListNode *node = head;
  24. while (node->next != NULL) {
  25. if (node->val == node->next->val) {
  26. ListNode *temp = node->next;
  27. node->next = node->next->next;
  28. delete temp;
  29. } else {
  30. node = node->next;
  31. }
  32. }
  33. return head;
  34. }
  35. };

Java

  1. /**
  2. * Definition for singly-linked list.
  3. * public class ListNode {
  4. * int val;
  5. * ListNode next;
  6. * ListNode(int x) { val = x; }
  7. * }
  8. */
  9. public class Solution {
  10. public ListNode deleteDuplicates(ListNode head) {
  11. if (head == null) return null;
  12. ListNode node = head;
  13. while (node.next != null) {
  14. if (node.val == node.next.val) {
  15. node.next = node.next.next;
  16. } else {
  17. node = node.next;
  18. }
  19. }
  20. return head;
  21. }
  22. }

源碼分析

  1. 首先進行異常處理,判斷head是否為NULL
  2. 遍歷鏈表,node->val == node->next->val時,保存node->next,便於後面釋放記憶體(非C/C++無需手動管理記憶體)
  3. 不相等時移動當前節點至下一節點,注意這個步驟必須包含在else中,否則邏輯較為複雜

while 循環處也可使用node != null && node->next != null, 這樣就不用單獨判斷head 是否為空了,但是這樣會降低遍歷的效率,因為需要判斷兩處。

複雜度分析

遍歷鏈表一次,時間複雜度為 O(n), 使用了一個變數進行遍歷,空間複雜度為 O(1).

Reference