Question: Implement a function that accepts a PositionalList L of n integers sorted in a nondecreasing order, and another value V, and determines in O(n) time
Implement a function that accepts a PositionalList L of n integers sorted in a nondecreasing order, and another value V, and determines in O(n) time if there are two elements of L that sum precisely to V. The function should return a pair of positions of such elements, if found, or None otherwise.
from DoublyLinkedList import _DoublyLinkedList as dlb class PositionalList(dlb): # --------- nested Position class ------- class Position: def __init__(self, container, node): self._container = container self._node = node def element(self): return self._node._element def __eq__(self, other): """Return True if other is a Position representing the same node as the instance""" return type(other) is type(self) and other._node is self._node def __ne__(self, other): # != """Return True if other does not represent the same location""" return not (self == other) # --- private method to create a position ------ # self represents a doubly linked list def _make_position(self, node): """Return Position instance for given node, None if sentinel""" if node is self._header or node is self._trailer: return None else: return self.Position(self, node) # --- private method to validate a position ---- # possible errors: p is not a Position, p is not in the current list, # p is no longer valid # purpose of method: return the node pointed to by p if p is a valid position # self in this scope is a doubly linked list def _validate(self, p): """Return position's node, ro raise exception""" if not isinstance(p, self.Position): raise TypeError("p must by of type Position") if p._container is not self: raise ValueError("p does not belong to this container") if p._node._next is None: raise ValueError("p is no longer valid") return p._node # -------------------------------------------- # ------ accessor methods -------------------- def first(self): """Returns position of the first element""" return self._make_position(self._header._next) def last(self): return self._make_position(self._trailer._previous) def before(self, p): """Returns position before p""" node = self._validate(p) return self._make_position(node._previous) def after(self, p): node = self._validate(p) return self._make_position(node._next) def __iter__(self): """Forward iterator of list elements""" # Allows the use of next() # Allows embedding in for loops pointer = self.first() while pointer is not None: yield pointer.element() # return element stored at this position pointer = self.after(pointer) # ------ mutator methods ----------------- # Override _insert_between() from parent to return a position instead of a node def _insert_between(self, e, predecessor, successor): node = super()._insert_between(e, predecessor, successor) return self._make_position(node) def add_first(self, e): return self._insert_between(e, self._header, self._header._next) def add_last(self, e): return self._insert_between(e, self._trailer._previous, self._trailer) def add_before(self, p, e): valid_position = self._validate(p) return self._insert_between(e, valid_position._previous, valid_position) def add_after(self, p, e): valid_position = self._validate(p) return self._insert_between(e, valid_position, valid_position._next) def delete(self, p): """Remove and return element at position p. Invalidate position.""" valid_position = self._validate(p) return self._delete_node(valid_position) def replace(self, p, e): valid_position = self._validate(p) element_to_return = valid_position._element valid_position._element = e return element_to_return Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
