Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Reverse Segments

The Problem

Given an array and a list of segment boundaries [l, r], reverse the elements within each segment in-place. Elements outside the segments are untouched.

Input:  arr = [1, 2, 3, 4, 5, 6, 7, 8],  segments = [(0, 3), (4, 7)]
Output: arr = [4, 3, 2, 1, 8, 7, 6, 5]
              ↑         ↑  ↑         ↑
              segment 0 reversed     segment 1 reversed

Examples

Example 1 — two segments

Input:  arr = [1, 2, 3, 4, 5, 6, 7, 8],  segments = [(0, 3), (4, 7)]
Output: [4, 3, 2, 1, 8, 7, 6, 5]

Example 2 — single segment in the middle

Input:  arr = [1, 2, 3, 4, 5],  segments = [(1, 3)]
Output: [1, 4, 3, 2, 5]

Example 3 — entire array as one segment

Input:  arr = [1, 2, 3, 4, 5],  segments = [(0, 4)]
Output: [5, 4, 3, 2, 1]

Example 4 — single-element segment

Input:  arr = [1, 2, 3],  segments = [(1, 1)]
Output: [1, 2, 3]   (reversing one element is a no-op)

Intuition

You already have the exact tool for this: the two-pointer reversal from “Flip Characters”. Reversing a segment [l, r] is identical to reversing the whole array — just start left = l and right = r instead of 0 and n-1.

For multiple segments, simply apply the two-pointer reversal once per segment. Each reversal is independent — the segments don’t overlap, so the order you process them in doesn’t matter.

---
config:
  theme: base
  themeVariables:
    primaryColor: "#dbeafe"
    primaryBorderColor: "#3b82f6"
    primaryTextColor: "#1e3a5f"
    lineColor: "#64748b"
    secondaryColor: "#ede9fe"
    tertiaryColor: "#fef9c3"
---
flowchart TB
  subgraph ORIG["Original:  [1, 2, 3, 4, 5, 6, 7, 8]"]
    direction LR
    A["1"] --- B["2"] --- C["3"] --- D["4"] --- E["5"] --- F["6"] --- G["7"] --- H["8"]
  end
  subgraph SEG0["Reverse segment (0,3):  left=0, right=3"]
    direction LR
    A1(["left=0"]) --> D1["4"] --- C1["3"] --- B1["2"] --- A2["1"] --- E1["5"] --- F1["6"] --- G1["7"] --- H1["8"]
    A2 --> D2(["right=3 done"])
  end
  subgraph SEG1["Reverse segment (4,7):  left=4, right=7"]
    direction LR
    A3["4"] --- B3["3"] --- C3["2"] --- D3["1"] --- E3(["left=4"]) --> H3["8"] --- G3["7"] --- F3["6"] --- E4["5"]
    E4 --> H4(["right=7 done"])
  end
  subgraph FINAL["Result:  [4, 3, 2, 1, 8, 7, 6, 5]"]
    direction LR
    R0["4"] --- R1["3"] --- R2["2"] --- R3["1"] --- R4["8"] --- R5["7"] --- R6["6"] --- R7["5"]
  end

  ORIG -->|"apply two-pointer reversal on [0,3]"| SEG0
  SEG0 -->|"apply two-pointer reversal on [4,7]"| SEG1
  SEG1 --> FINAL

Reversing two segments of [1,2,3,4,5,6,7,8] — each segment is reversed independently using the standard two-pointer swap-and-converge.


Applying the Diagnostic Questions

CheckAnswer for Reverse Segments
✅ Two positions simultaneously?Yes — arr[left] and arr[right] are swapped together at each step within each segment
✅ One near start, one near end?Yes — for each segment (l, r), left = l, right = r
✅ Both move inward?Yes — left++, right-- within each segment’s reversal
✅ Simple work at each step?Yes — one swap per iteration

Reverse Segments is structurally identical to Flip Characters — the only difference is that left and right start from a given (l, r) pair instead of (0, n-1). The two-pointer pattern is unchanged; the input just parameterises the range.

Why is this still “direct application” and not something more complex? No transformation of the data is needed — the segment boundaries are given directly, and the reversal within each boundary is the same swap-and-converge loop. There’s no searching for the right range, no sorting, no condition-based pointer movement. Two pointers enter a segment, march toward each other, and exit. The only outer logic is iterating through the list of segments.

What makes each segment’s reversal independent? Non-overlapping segments modify distinct array regions — each reverse_segment(arr, l, r) call touches only indices l through r. Because no two calls share an index, processing order is irrelevant: process segment 0 first or last, the result is the same. This independence is what allows the outer loop to be a simple for l, r in segments — no coordination between iterations needed.


Approach

  1. For each (l, r) segment in the segments list:
    • Set left = l, right = r
    • While left < right: swap arr[left] and arr[right], left++, right--
  2. Done — all segments reversed in-place

Solution

from typing import List, Tuple

class Solution:
    def reverse_segment(self, arr: List[int], l: int, r: int) -> None:
        """Reverse arr[l..r] in-place using two pointers."""
        left, right = l, r
        while left < right:
            arr[left], arr[right] = arr[right], arr[left]
            left  += 1
            right -= 1

    def reverse_segments(
        self,
        arr: List[int],
        segments: List[Tuple[int, int]]
    ) -> None:
        """Reverse each segment in-place."""
        for l, r in segments:
            self.reverse_segment(arr, l, r)


# --- Test ---
sol = Solution()

a1 = [1, 2, 3, 4, 5, 6, 7, 8]
sol.reverse_segments(a1, [(0, 3), (4, 7)])
print(a1)   # [4, 3, 2, 1, 8, 7, 6, 5]

a2 = [1, 2, 3, 4, 5]
sol.reverse_segments(a2, [(1, 3)])
print(a2)   # [1, 4, 3, 2, 5]

a3 = [1, 2, 3, 4, 5]
sol.reverse_segments(a3, [(0, 4)])
print(a3)   # [5, 4, 3, 2, 1]

a4 = [1, 2, 3]
sol.reverse_segments(a4, [(1, 1)])
print(a4)   # [1, 2, 3]

Dry Run — Example 1

arr = [1, 2, 3, 4, 5, 6, 7, 8]

Segment (0, 3): left=0, right=3

StepleftrightSwapArray
1031 ↔ 4[4, 2, 3, 1, 5, 6, 7, 8]
2122 ↔ 3[4, 3, 2, 1, 5, 6, 7, 8]
21stop

Segment (4, 7): left=4, right=7

StepleftrightSwapArray
1475 ↔ 8[4, 3, 2, 1, 8, 6, 7, 5]
2566 ↔ 7[4, 3, 2, 1, 8, 7, 6, 5]
65stop

Result: [4, 3, 2, 1, 8, 7, 6, 5]


Complexity Analysis

Let n = array length, k = number of segments, s = total elements covered by all segments.

ComplexityReasoning
TimeO(s)Each reversed element is visited once; O(n) in the worst case (all segments cover the full array)
SpaceO(1)Only pointer variables — in-place reversal

Edge Cases

ScenarioSegmentEffect
Single element(i, i)left = right — loop never runs, no-op
Entire array(0, n-1)Full reversal
Overlapping segments(0,4), (2,6)Undefined — this function assumes non-overlapping. Overlapping produces incorrect results.
Out-of-bounds(-1, 5)Caller’s responsibility to validate indices

Key Takeaway

Reverse Segments shows that the two-pointer reversal is a reusable utility — not just a technique for one specific problem. By extracting it into reverse_segment(arr, l, r), you get a building block that can be called on any sub-range of any array. The next problem, Reverse Word Order, uses exactly this building block twice in sequence.