elementwithcachedmax collections namedtuple ('elementwithcachedmax '('element ''max ')def __init__ (self)self _element_with_cached_max [def empty (self)return len(self _element_with_cached_max = def max(self)if self empty ()raise indexerror ('max ()empty stack 'return self _element_with_cached_max - max def pop(self)if self empty ()raise indexerror ('pop ()empty stack 'return self _element_with_cached_max pop (element def push(self )self _element_with_cached_max append self elementwithcachedmax (xx if self empty (else max(xself max ()))each of the specified methods has time complexity ( the additional space complexity is ( )regardless of the stored keys we can improve on the best-case space needed by observing that if an element being pushed is smaller than the maximum element already in the stackthen can never be the maximumso we do not need to record it we cannot store the sequence of maximum values in separate stack because of the possibility of duplicates we resolve this by additionally recording the number of occurrences of each maximum value see figure on the following page for an example class stack class maxwithcount def __init__ (self max count )self max self count max count def __init__ (self)self _element [self _cached_max_with_count [def empty (self)return len(self _element = def max(self)if self empty ()raise indexerror ('max ()empty stack 'return self _cached_max_with_count - max