educative.io

In-place solution with O(m+n) time

If we allow O(m) extra space complexity then we can solve this in O(m+n) which is far better than Solution 2:

def merge_lists(lst1, lst2):
   """
   Extend the longer list and start from the end of the two lists.
   In each iteration find the largest number between them and add that
   at the end of the extended list.
   """
   i, j = len(lst1) - 1, len(lst2) - 1
   if len(lst1) >= len(lst2):
       result = lst1
       result.extend(lst2)
   else:
       result = lst2
       result.extend(lst1)
   k = len(result) - 1
   while i >= 0 and j >= 0:
       if lst1[i] >= lst2[j]:
           result[k] = lst1[i]
           i -= 1
       else:
           result[k] = lst2[j]
           j -= 1
       k -= 1
   
   while i >= 0:
       result[k] = lst1[i]
       i -= 1
       k -= 1
   
   while j >= 0:
       result[k] = lst2[j]
       j -= 1
       k -= 1
   
   return result

In case we want to go further and solve the question in O(1) extra space complexity, then we can modify heap sort such that it treats the two separate lists as one list and run sorting in-place so we get extra space complexity of O(1) and time complexity of O((m+n)*log(m+n)). Here, result is just a “fake” list that retrieves the items from lst1 or lst2 based on the index:

def getitem(i):
    if i < len(lst1):
        return lst1[i]
    else:
        return lst2[len(lst1) - i]

def setitem(i, val):
    if i < len(lst1):
        lst1[i] = val
    else:
        lst2[len(lst1) - i] = val