More from the Programming Interviews Exposed book (see last post). In this problem you take a double linked list (where each node knows its previous and next nodes) with child elements, and flatten it. Then unflatten it back to its original structure. It took me a few minutes to understand using recursion for unflattening.
class Node:
def __init__(self,data,prev=None,next=None,child=None):
self.data=data
self.prev=prev
self.next=next
self.child=child
class ListFlattener:
"""
>>> node1=Node(1)
>>> node5=Node(5)
>>> node1.child=node5
>>> node2=Node(2)
>>> node3=Node(3,node1,None,node2)
>>> node1.next=node3
>>> node4=Node(4,node2)
>>> node2.next=node4
>>> ListFlattener.listAsArray(node1)
[1, 3]
>>> ListFlattener.flattenList(node1)
>>> ListFlattener.listAsArray(node1)
[1, 3, 5, 2, 4]
>>> ListFlattener.unflattenList(node1)
>>> ListFlattener.listAsArray(node1)
[1, 3]
>>> ListFlattener.flattenList(node1)
>>> ListFlattener.listAsArray(node1)
[1, 3, 5, 2, 4]
>>> ListFlattener.listAsArray(ListFlattener.findTail(node1),False)
[4, 2, 5, 3, 1]
"""
@staticmethod
def flattenList(head):
curr=head
tail=ListFlattener.findTail(head)
while curr!=None:
if curr.child!=None:
tail=ListFlattener.appendChildToEnd(curr,curr.child,tail)
curr=curr.next
@staticmethod
def unflattenList(head):
curr=head
while curr!=None:
if curr.child!=None:
curr.child.prev.next=None
curr.child.prev=None
ListFlattener.unflattenList(curr.child)
curr=curr.next
@staticmethod
def appendChildToEnd(node,child,tail):
tail.next=child
child.prev=tail
return ListFlattener.findTail(child)
@staticmethod
def findTail(node):
while node.next!=None:
node=node.next
return node
@staticmethod
def listAsArray(node,forward=True):
list=[]
while node!=None:
list.append(node.data)
if forward:
node=node.next
else:
node=node.prev
return list
if __name__ == "__main__":
import doctest
doctest.testmod()
- class Node:
- def __init__(self,data,prev=None,next=None,child=None):
- self.data=data
- self.prev=prev
- self.next=next
- self.child=child
- class ListFlattener:
- """
- >>> node1=Node(1)
- >>> node5=Node(5)
- >>> node1.child=node5
- >>> node2=Node(2)
- >>> node3=Node(3,node1,None,node2)
- >>> node1.next=node3
- >>> node4=Node(4,node2)
- >>> node2.next=node4
- >>> ListFlattener.listAsArray(node1)
- [1, 3]
- >>> ListFlattener.flattenList(node1)
- >>> ListFlattener.listAsArray(node1)
- [1, 3, 5, 2, 4]
- >>> ListFlattener.unflattenList(node1)
- >>> ListFlattener.listAsArray(node1)
- [1, 3]
- >>> ListFlattener.flattenList(node1)
- >>> ListFlattener.listAsArray(node1)
- [1, 3, 5, 2, 4]
- >>> ListFlattener.listAsArray(ListFlattener.findTail(node1),False)
- [4, 2, 5, 3, 1]
- """
- @staticmethod
- def flattenList(head):
- curr=head
- tail=ListFlattener.findTail(head)
- while curr!=None:
- if curr.child!=None:
- tail=ListFlattener.appendChildToEnd(curr,curr.child,tail)
- curr=curr.next
- @staticmethod
- def unflattenList(head):
- curr=head
- while curr!=None:
- if curr.child!=None:
- curr.child.prev.next=None
- curr.child.prev=None
- ListFlattener.unflattenList(curr.child)
- curr=curr.next
- @staticmethod
- def appendChildToEnd(node,child,tail):
- tail.next=child
- child.prev=tail
- return ListFlattener.findTail(child)
- @staticmethod
- def findTail(node):
- while node.next!=None:
- node=node.next
- return node
- @staticmethod
- def listAsArray(node,forward=True):
- list=[]
- while node!=None:
- list.append(node.data)
- if forward:
- node=node.next
- else:
- node=node.prev
- return list
- if __name__ == "__main__":
- import doctest
- doctest.testmod()
class Node:
def __init__(self,data,prev=None,next=None,child=None):
self.data=data
self.prev=prev
self.next=next
self.child=child
class ListFlattener:
"""
>>> node1=Node(1)
>>> node5=Node(5)
>>> node1.child=node5
>>> node2=Node(2)
>>> node3=Node(3,node1,None,node2)
>>> node1.next=node3
>>> node4=Node(4,node2)
>>> node2.next=node4
>>> ListFlattener.listAsArray(node1)
[1, 3]
>>> ListFlattener.flattenList(node1)
>>> ListFlattener.listAsArray(node1)
[1, 3, 5, 2, 4]
>>> ListFlattener.unflattenList(node1)
>>> ListFlattener.listAsArray(node1)
[1, 3]
>>> ListFlattener.flattenList(node1)
>>> ListFlattener.listAsArray(node1)
[1, 3, 5, 2, 4]
>>> ListFlattener.listAsArray(ListFlattener.findTail(node1),False)
[4, 2, 5, 3, 1]
"""
@staticmethod
def flattenList(head):
curr=head
tail=ListFlattener.findTail(head)
while curr!=None:
if curr.child!=None:
tail=ListFlattener.appendChildToEnd(curr,curr.child,tail)
curr=curr.next
@staticmethod
def unflattenList(head):
curr=head
while curr!=None:
if curr.child!=None:
curr.child.prev.next=None
curr.child.prev=None
ListFlattener.unflattenList(curr.child)
curr=curr.next
@staticmethod
def appendChildToEnd(node,child,tail):
tail.next=child
child.prev=tail
return ListFlattener.findTail(child)
@staticmethod
def findTail(node):
while node.next!=None:
node=node.next
return node
@staticmethod
def listAsArray(node,forward=True):
list=[]
while node!=None:
list.append(node.data)
if forward:
node=node.next
else:
node=node.prev
return list
if __name__ == "__main__":
import doctest
doctest.testmod()