</> MAANG.io
coding interview · 301

Advanced

Advanced coding interview preparation covering complex algorithms, system design, and optimization techniques for senior-level positions.

0/95 solved 0% complete

Angular and Two-Pointer

What is this?

Both problems here are easy once you stop looking at the data you were given and look at a different axis. Points scattered on a plane become a one-dimensional list of angles. A quadratic applied to a sorted array is not sorted — but it is monotonic outward from its vertex, which means the extremes sit at the two ends and can be collected inward.

Neither needs a clever data structure. Both need you to notice which ordering already exists.

flowchart TD A["the given axis is awkward"] --> B["Maximum Number of Visible Points"] A --> C["Sort Transformed Array"] B --> B1["convert points to ANGLES from the viewer"] B1 --> B2["sort, then append every angle + 360"] B2 --> B3["an ordinary window now spans the wrap"] C --> C1["a parabola is monotonic outward from its vertex"] C1 --> C2["extremes are at the two ends"] C2 --> C3["two pointers fill the result outside-in"]

💡 Fun fact: the + 360 duplication is the angular version of a trick that appears throughout the curriculum — linearise a circular problem by writing the data twice. It is the same move that makes circular next-greater-element work by iterating 2n times with % n, and the same reason a doubled string contains every rotation of itself. Whenever wraparound is the only complication, duplicating the sequence usually removes it entirely.

🔓 The 2 problems in this chapter are free. Sign in with Google or Microsoft to start solving.


The one-line idea: find the axis on which the data is already ordered — the angle from the viewer, or the distance from a parabola's vertex — and a standard linear technique applies without any new machinery.


1. Points become angles

import math
angles = []
same = 0
for x, y in points:
    if [x, y] == location:
        same += 1                      # a point AT the viewer is always visible
        continue
    angles.append(math.degrees(math.atan2(y - location[1], x - location[0])))

angles.sort()
angles += [a + 360 for a in angles]    # linearise the wraparound

best = left = 0
for right in range(len(angles)):
    while angles[right] - angles[left] > angle:
        left += 1
    best = max(best, right - left + 1)
return best + same

Three details decide correctness. atan2 handles all four quadrants and the vertical case, where a naive atan(y/x) divides by zero. Points located exactly at the viewer have no defined angle and are visible regardless — count them separately and add at the end. And the duplication must happen after sorting, so the appended copies stay in order.

Floating point deserves a word: comparing angles[right] - angles[left] > angle on values produced by atan2 can misjudge a point exactly on the boundary. Where the problem's tolerance matters, compare with a small epsilon.

2. A parabola is monotonic from its ends

Applying f(x) = ax² + bx + c to a sorted array does not give a sorted result — but the shape is predictable. When a > 0 the parabola opens upward, so the largest values are at the two ends of the input and the smallest is somewhere in the middle. When a < 0 it is the reverse.

So fill the output from the outside in:

res = [0] * len(nums)
i, j = 0, len(nums) - 1
write = len(nums) - 1 if a >= 0 else 0
step = -1 if a >= 0 else 1
while i <= j:
    fi, fj = f(nums[i]), f(nums[j])
    if (a >= 0) == (fi > fj):          # take whichever end wins for this orientation
        res[write] = fi; i += 1
    else:
        res[write] = fj; j -= 1
    write += step
return res

a == 0 makes it linear, and folding it in with a >= 0 handles it correctly — the values are then monotonic in the same direction as the input, and the comparison still picks the right end.


3. A 30-second worked example (the wrap)

Angles at 350° and 10°, with a field of view of 30°. On the raw sorted list [10, 350] the gap reads as 340° and the window sees one point.

sorted:          [10, 350]
+360 duplicate:  [10, 350, 370, 710]

window with angle = 30:
   left=350, right=370  →  370 - 350 = 20 <= 30  ✓  two points visible

The two points are 20° apart across the zero mark, and the duplication is what lets a left-to-right window see it. Without it, no window over [10, 350] ever contains both.


4. Where you'll actually meet this

  • Games and simulation. Field-of-view and line-of-sight queries — how many entities fall inside a cone from the player.
  • Robotics. LIDAR and sensor sweeps, where readings are naturally angular and the zero crossing is a real source of bugs.
  • Radar and surveillance. Counting contacts within a bearing window.
  • Computational geometry. Angular sweeps underpin convex hull and visibility algorithms.
  • Signal processing. Applying a quadratic response curve to sorted measurements and needing the result ordered.

5. Problems in this chapter

▶ Maximum Number of Visible Points

Most points visible within a fixed angular field of view. Convert to angles with atan2, sort, append every angle + 360, then run an ordinary window; count points at the viewer separately.
Pattern: angular window with wraparound duplication. Target: O(n log n) time, O(n) space.

▶ Sort Transformed Array

Apply ax² + bx + c to a sorted array and return the sorted result. Two pointers fill outside-in, because a parabola is monotonic outward from its vertex.
Pattern: two-pointer fill by orientation. Target: O(n) time — better than the O(n log n) transform-then-sort.


6. Common pitfalls 🚫

  • Using atan instead of atan2. It loses the quadrant and divides by zero on vertical alignments.
  • Forgetting points at the viewer. They have no angle, are always visible, and must be added after the window.
  • Duplicating before sorting. The appended copies must preserve order or the window breaks.
  • Ignoring floating-point tolerance on points exactly at the field-of-view boundary.
  • Sorting after the transform. Correct, and O(n log n) for a problem that is O(n).
  • Handling a == 0 as a special case. Folding it in with a >= 0 works; a separate branch is easy to get backwards.
  • Writing the output forwards when a > 0. The largest values come first, so the write pointer must start at the end and move backwards.

7. Key takeaways

  1. Change the axis. Points become angles; a parabola becomes distance from its vertex.
  2. Duplicate to linearise a circle. + 360 here, 2n iterations elsewhere — the same idea.
  3. atan2, always, for anything angular.
  4. Handle the degenerate point — one located exactly at the viewer — outside the main loop.
  5. A parabola's extremes are at the input's ends, which is what makes an outside-in fill correct.
  6. Two pointers beat a sort whenever the output ordering can be derived rather than computed.
  7. Why interviewers like it: both problems look geometric and are solved by ordinary linear techniques once the right ordering is spotted. That spotting is the whole test.

Order: Maximum Number of Visible Points → Sort Transformed Array.

Maximum Number of Visible Points

Core idea: You stand at a fixed location and can rotate your gaze freely, but your eyes only span a fixed angle-wide cone at a time. A point is visible if its direction from you falls inside that cone. The direction of each point is its polar angleatan2(dy, dx) — and rotating your gaze is just sliding that fixed-width window of angles around the circle. So the 2D "what can I see" question collapses to a 1D one: sort all the polar angles, then slide a window of width angle and count the most angles it ever covers. Two wrinkles make it interview-worthy. (1) Wrap-around: angles live on a circle (atan2 returns (-180°, 180°]), so a window can straddle the ±180° seam. Fix it by duplicating the sorted list with every angle +360 — now any circular window appears as a plain contiguous window somewhere in the doubled array. (2) Points exactly at location have no direction at all (atan2(0,0) is meaningless), but they're always visible no matter where you look — so count them separately and add them at the end. Sorting dominates: O(n log n).


The problem, rephrased

You're standing still in a field at a fixed spot, holding a camera with a fixed field of view — say it spans angle degrees. You can spin around in place as much as you like, but at any instant the camera only captures the wedge of directions inside that cone. Scattered around you are some landmarks. Aim the camera in the single best direction — which way captures the most landmarks at once?

Two subtleties: a landmark you're standing on top of is always in frame (it's right at your feet, every direction "sees" it); and because directions wrap around a full circle, the best wedge might point "backwards" across the seam where +180° meets -180°.

Formally — this is LeetCode 1610 — Maximum Number of Visible Points: given points (a list of [x, y]), an integer angle (your field of view in degrees), and your location = [x, y], return the maximum number of points you can see by rotating your view. A point is visible if the angle between your viewing direction and the direction to the point is within angle / 2 on either side — equivalently, if it falls inside some angle-wide window of directions. Points equal to location are always counted.

Input Means Output
points=[[2,1],[2,2],[3,3]], angle=90, location=[1,1] All three lie within a 90° wedge 3
points=[[2,1],[2,2],[3,4],[1,1]], angle=90, location=[1,1] One point is at your location (always seen) + 3 in a 90° wedge 4
points=[[1,0],[2,1]], angle=13, location=[1,1] The two directions differ by more than 13° 1

The interesting word is angle — it turns a geometry problem into a windowing problem the moment you realize a viewing direction is just a position on the circle of polar angles.


Sign in to continue reading

The rest of this lesson is available with a free account. Signing in with Google or Microsoft is free.

Sign in to read the full lesson

Sign in to MAANG.io

Use your Google or Microsoft account — no password to remember.

Continue with Google Continue with Microsoft

Please accept the terms above to continue.