【问题标题】:Removing Duplicates in a linked list recursively递归删除链表中的重复项
【发布时间】:2017-08-22 10:40:28
【问题描述】:

我正在尝试编写一个递归函数来删除链表中所有相邻的重复项。但是,我的功能无法正常工作。

这是我的尝试:

class Node:
    """Node in a linked list"""

    def __init__(self: 'Node', value: object = None, next: 'Node' = None) -> None:
        """Create Node self with data value and successor next."""
        self.value, self.next = value, next

def remove_dup(lnk):
    if not lnk or lnk.next:
        return lnk
    if lnk.value == lnk.next.value:
        lnk.next = lnk.next.next
    else:
        return remove_dup(lnk.next)

【问题讨论】:

    标签: python python-3.x recursion linked-list


    【解决方案1】:

    not 优先于or,因此您需要重复not,或者将or 表达式作为and 放在括号中:

    if not (lnk and lnk.next):
    

    此外,当您找到重复项时,您不应停止该过程,因为重复项可能出现两次以上,并且可能还有其他重复项。

    所以它可能看起来像这样(带有将列表表示为字符串的函数):

    class Node:
        """Node in a linked list"""
    
        def __init__(self: 'Node', value: object = None, next: 'Node' = None) -> None:
            """Create Node self with data value and successor next."""
            self.value, self.next = value, next
    
        def __repr__(self):
            return str(self.value) + ('->' + str(self.next) if self.next else '')
    
    def remove_dup(lnk):
        if not (lnk and lnk.next):
            return lnk
        if lnk.value == lnk.next.value:
            lnk.next = lnk.next.next
            return remove_dup(lnk) # there might be more duplicates...
        else:
            return remove_dup(lnk.next)       
    
    # Sample data and test
    lst = Node(1, Node(3, Node(3, Node(3, Node(4, Node(4, Node(5)))))))
    print (lst) # 1->3->3-3->4->4->5
    remove_dup(lst)
    print (lst) # 1->3->4->5
    

    看到它在repl.it上运行

    其他一些改进

    函数remove_dup 非常适合作为Node 的方法。

    如果您可以将链表作为标准列表进行读写,那就太好了。类方法可用于从值列表创建链表,而 __iter__ 方法可以使您的类可迭代。

    那么它可能看起来像这样:

    class Node:
        """Node in a linked list"""
    
        def __init__(self: 'Node', value: object = None, next: 'Node' = None) -> None:
            """Create Node self with data value and successor next."""
            self.value, self.next = value, next
    
        def __iter__(self):
            yield self.value
            if self.next:
                yield from iter(self.next) # this needs Python 3.4+
    
        def __repr__(self):
            return '->'.join(map(str, list(self))) # uses __iter__
    
        def remove_dup(self):
            if not self.next:
                return self
            if self.value == self.next.value:
                self.next = self.next.next
                return self.remove_dup() # there might be more duplicates...
            else:
                return self.next.remove_dup()
    
        @classmethod
        def from_list(cls, values):
            head = None
            for value in reversed(values):
                head = cls(value, head)
            return head
    
    lst = Node.from_list([1, 3, 3, 3, 4, 4, 5])
    print (lst) # 1->3->3->3->4->4->5
    lst.remove_dup()
    print (lst) # 1->3->4->5
    print(list(lst)) # [1, 3, 4, 5]
    

    开启repl.it

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-30
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多