def reconstruct_lcs_solution(table, string_a, string_b):
    """
    to reconstruct the solution (actual string)
        1. start at table[-1][-1] for max length
        2. if string_a[i] == string_b[j], chars match, then the current position we are at is
           associated with table[i-1][j-1] (as to make the table we extend the max sub seq by 1 when they machted)
           so update our current position and add the common character we were at to output
           string_a[i] is added to output
        3. if not match, then the number would have come from max(left, top) so move there and update our position
           nothing has been added to LCS
        continue until reaching 0 (where table[i][j] = 0 or i or j, boundary case) and we are done

    Time Complexity to make solution: O(a+b) where a is len(string_a) and b is len(string_b)
        this is because we loop until i or j = 0 and each pass decrements one of i or j or both
        so at worst bound is when only one of i or j decrements each pass which is O(i + j)

    :return: longest common subsequence
    """
    solution = []
    i = len(string_a)
    j = len(string_b)
    # remember table has i columns indexed from 0 to i
    while table[i][j] > 0:
        if string_a[i-1] == string_b[j-1]:      # remember need to index-1 for strings, only the table has + 1 row, col
            solution.append(string_a[i-1])      # add common element to solution
            i -= 1                              # decrement i and j (go to top left diagonal)
            j -= 1
        else:                                   # no match
            top = table[i-1][j]
            left = table[i][j-1]
            if top >= left:
                i -= 1                          # decrement j to update our position
            else:                               # top < left
                j -= 1                          # decrement i to update our position
    return solution[::-1]