|
1 |
| -from typing import Any, Union, Optional, Tuple |
| 1 | +from typing import Any, Union, Optional, Dict |
2 | 2 |
|
3 | 3 | from datastructures.stacks import Stack
|
4 | 4 | from .node import SingleNode
|
@@ -440,24 +440,39 @@ def contains_cycle(self):
|
440 | 440 | # fast runner hit the end of the list
|
441 | 441 | return False
|
442 | 442 |
|
443 |
| - def remove_duplicates(self): |
| 443 | + def remove_duplicates(self) -> Optional[SingleNode]: |
444 | 444 | """
|
445 |
| - Removes duplicates from linked list |
| 445 | + Removes duplicates from linked list. Uses a dictionary to keep track of seen values in the linked list. |
| 446 | + For every encountered duplicate value, it is discarded and removed from the linked list. |
| 447 | +
|
| 448 | + Complexity: |
| 449 | + Where n is the number of nodes in the linked list: |
| 450 | +
|
| 451 | + Time O(n): as this iterates through each node in the linked list checking its value against what's in the |
| 452 | + dictionary |
| 453 | +
|
| 454 | + Space O(n); a dictionary is used to store duplicate values in the linked list. In the worst case no duplicates |
| 455 | + exist so, the dictionary has all the values from every node in the linked list. |
446 | 456 | """
|
447 | 457 |
|
448 | 458 | if self.head is None or self.head.next is None:
|
449 | 459 | return self.head
|
450 | 460 |
|
| 461 | + seen: Dict[Any, bool] = dict() |
451 | 462 | current = self.head
|
452 |
| - next_ = self.head.next |
| 463 | + previous: Optional[SingleNode] = None |
453 | 464 |
|
454 |
| - while current and next_: |
455 |
| - if next_.data == current.data: |
456 |
| - current.next = next_.next |
457 |
| - next_ = next_.next |
| 465 | + while current: |
| 466 | + if current.data in seen: |
| 467 | + # remove node |
| 468 | + previous.next = current.next |
| 469 | + current = None |
458 | 470 | else:
|
459 |
| - current = current.next |
460 |
| - next_ = next_.next |
| 471 | + # add node data to seen |
| 472 | + seen[current.data] = True |
| 473 | + previous = current |
| 474 | + |
| 475 | + current = previous.next |
461 | 476 |
|
462 | 477 | return self.head
|
463 | 478 |
|
@@ -720,7 +735,8 @@ def reverse_list(head_node: SingleNode) -> SingleNode:
|
720 | 735 | # tail of previous k-group to fix our linked list pointers
|
721 | 736 | tail = dummy
|
722 | 737 |
|
723 |
| - # set a tracking node, tracking_node, to cycle through linked list and a head of current linked list, current_head |
| 738 | + # set a tracking node, tracking_node, to cycle through linked list and a head of current linked list, |
| 739 | + # current_head |
724 | 740 | tracking_node, current_head = self.head, self.head
|
725 | 741 |
|
726 | 742 | # while tracking node is tracking a node and hasn't reached end
|
|
0 commit comments