Merge two sorted linked lists and return it as a sorted list. The list should be made by splicing together the nodes of the first two lists.
Input: l1 = [1,2,4], l2 = [1,3,4]
Output: [1,1,2,3,4,4]
Example 2:
Input: l1 = [], l2 = []
Output: []
Example 3:
Input: l1 = [], l2 = [0]
Output: [0]
Intuition
We can achieve the same idea via iteration by assuming that l1
is entirely less than l2
and processing the elements one-by-one, inserting elements of l2
in the necessary places in l1
.
Algorithm
First, we set up a false “prehead
" node that allows us to easily return the head of the merged list later. We also maintain a prev
pointer, which points to the current node for which we are considering adjusting its next
pointer. Then, we do the following until at least one of l1
and l2
points to null
: if the value at l1
is less than or equal to the value at l2
, then we connect l1
to the previous node and increment l1
. Otherwise, we do the same, but for l2
. Then, regardless of which list we connected, we increment prev
to keep it one step behind one of our list heads.
After the loop terminates, at most one of l1
and l2
is non-null
. Therefore (because the input lists were in sorted order), if either list is non-null
, it contains only elements greater than all of the previously-merged elements. This means that we can simply connect the non-null
list to the merged list and return it.
To see this in action on an example, check out the animation below:
Complexity Analysis
- Time complexity : O(n+m)
- Because exactly one of
l1
andl2
is incremented on each loop iteration, thewhile
loop runs for a number of iterations equal to the sum of the lengths of the two lists. All other work is constant, so the overall complexity is linear. - Space complexity : O(1)
- The iterative approach only allocates a few pointers, so it has a constant overall memory footprint.