Created
March 1, 2019 22:48
-
-
Save wpm/6c14c25d7da10fb71f77e662a10d1025 to your computer and use it in GitHub Desktop.
Maximal Fully-Ordered Sublists
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def maximal_fully_ordered_sublists(s: List[T]) -> List[List[T]]: | |
""" | |
Find maximum-length sequences of in-order items in a list. | |
Let s be a list of items over which there exists a total ordering defined by the < operator. | |
Let a fully-ordered sublist s' of s be s with elements removed so that the elements of s' are monotonically | |
increasing. | |
The maximal fully-ordered sublists of s are the set of fully-ordered sublists such that no sublist is contained in | |
another one. | |
For example, given the list (R, S, T, A, B, U, V) with alphabetic ordering, the fully-ordered sublists would be | |
R, S, T, U, V | |
A, B, U, V | |
:param s: list of items | |
:return: maximal fully-ordered sublists of s in order from longest to shortest | |
""" | |
# Build a topologically sorted DAG between the items of s in which the edge a -> b can only exist if b comes after | |
# a in s. | |
if not s: | |
return [s] | |
s = sorted(enumerate(s), key=itemgetter(1)) | |
g = {s[-1][1]: None} | |
agenda = [] | |
for x, y in sliding_window(2, s): | |
remaining_agenda = [] | |
agenda.insert(0, x) | |
while agenda: | |
z = agenda.pop(0) | |
if z[0] < y[0]: | |
g[z[1]] = y[1] | |
else: | |
g[z[1]] = None | |
remaining_agenda.insert(0, z) | |
agenda = remaining_agenda.copy() | |
# Find all the paths in the DAG starting at nodes that have no predecessors. | |
paths = [] | |
minima = set(g.keys()) - set(g.values()) | |
for x in minima: | |
path = [] | |
while x is not None: | |
path.append(x) | |
x = g[x] | |
paths.append(path) | |
# Sort these paths from largest to smallest. (And then in lexicographic order to break ties.) | |
return sorted(paths, key=lambda p: (-len(p), tuple(p))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment