Squared deviations in sorted order

Two pointers Junior Python 3.13+ Reviewed By Best Latest Apps

Pick the fix

Squares must come out sorted. Which fill order works with two pointers in one pass?

Options

Choose an answer, then open Show answer below to check it.

Show answer

Answer: A Fill the output from the back with the larger end square

Right: the largest remaining square is always at one of the two ends.

Only the maximum is guaranteed to sit at an end of a sorted list with negatives, so the output is built from its largest slot down.

Why not the others?
  • B Fill from the front with the smaller end square. The smallest square is near zero, usually in the middle, not at an end.
  • C Fill from the front, then reverse at the end. That still needs the smallest square first, which the ends do not give you.

30-second answer

The largest square comes from one of the two ends, because the most negative and the most positive values have the biggest magnitudes. Compare the ends, write the bigger square at the back of the output, and move that pointer inward. Filling from the back gives sorted output in one O(n) pass; the output takes O(n) space and the rest is O(1).

Practise saying it · 45 s. No recording, just a timer

Explain how two pointers give sorted squares in O(n).

Say your answer out loud, then check which of these points you covered:

  • Biggest magnitude at an end
  • Fill from the back
  • O(n) time

Deep dive

Squaring then sorting is O(n log n): correct, and a fine first answer to mention.

Filling from the back is the trick: the biggest square is easy to find, the smallest is not.

With all non-negative input the squares are already sorted; the two-pointer version handles every case without branching.

Python solution Ran on Python 3.13.5 · mypy --strict
Python 3.13
def sorted_squares(dev: list[int]) -> list[int]:
    out = [0] * len(dev)
    lo, hi = 0, len(dev) - 1
    for pos in range(len(dev) - 1, -1, -1):
        if abs(dev[lo]) > abs(dev[hi]):
            out[pos] = dev[lo] * dev[lo]
            lo += 1
        else:
            out[pos] = dev[hi] * dev[hi]
            hi -= 1
    return out

Common mistakes

  • Filling from the front, which requires finding the value closest to zero first.
  • Comparing raw values instead of absolute values or squares at the two ends.

Senior take & follow-ups

Say 'the biggest square is at an end' first. That observation is the whole solution.

Follow-up questions

Think of your answer first, then open the hint.

  1. What if the input were unsorted?

    Show hint

    Then O(n log n) is the honest answer: sort the squares.

  2. How would you merge without extra space?

    Show hint

    You need the output list anyway; the O(1) refers to extra working space.

What each operation costs: Arrays · Array Operations

From the author

DSA Master - Data & Algorithms

Free on iPhone and iPad: watch 50+ data structures and algorithms step through animations, run the code in the playground, and try the daily challenge.

Suggest a fix if something here is wrong or out of date.