First array problems

Walk an array once to sum it, count in it, check its order, and reverse it in place.

Pattern: Linear scan15 min read
Quick recall3 questions
  1. 01Why can a loop that looks for divisors stop at √n?

    Divisors come in pairs, small × big. The small side of each pair is at most √n, and the big side is n / i.

  2. 02What does [3, 10, 2].sort() return in JavaScript?

    [10, 2, 3]. The default sort compares text. Pass (a, b) => a - b to sort numbers.

  3. 03Two loops over the array, one after the other. What is the Big O?

    O(n + n), which is O(n). Only a loop inside a loop gives O(n²).

Most array problems start the same way: walk the array once and keep a running answer. Sum it, count in it, find its largest value.

The tricky part is knowing when one walk is enough. This lesson's main problem, "is this array sorted?", looks like it needs every pair compared. It needs only the neighbours.

The linear scan: one pass, one running answer

A keeps one variable that holds the answer for the items seen so far. Each new item updates it.

Under each item, the total so far. At the pointer: 3 + 8 + 1 = 12.
int sum(int[] arr) {
    int total = 0; // the sum of the items seen so far
    for (int x : arr) total += x;
    return total;
}
  • The Python version is sum_array, because sum is a built-in. sum(arr) does the same loop for you.
  • In Java, make total a long when the sum can pass about 2 × 10⁹.

Two of this lesson's problems are this loop with a different middle line:

ProblemRunning answerUpdate for each x
Sum of Array Elementstotal = 0total += x
Count of odd numberscount = 0add 1 when x % 2 != 0

Test odd numbers with != 0, not == 1. In Java and TypeScript, -3 % 2 is -1, so == 1 misses negative odd numbers. Python gives 1, but != 0 is right in all three.

Both read each item once and keep one number: O(n) time, O(1) extra space.

Read the problem

Problem: Check if the Array is Sorted In ≤ 10⁶
it asks
Return true when every value is at least as large as the value before it. Otherwise return false.
example 1
in arr = [1, 2, 3, 4, 5] out true
example 2
in arr = [5, 4, 6, 7, 8] out false

4 comes after 5.

limits
  • 1 ≤ n ≤ 10⁶
  • −10⁹ ≤ arr[i] ≤ 10⁹
budget
About 10⁸ steps run in one second. With n up to 10⁶, aim for O(n log n) or faster.
Which pattern? Decide first, then open.

“sorted in non-decreasing order”each value compared with the one before it

“n up to 10⁶”one pass, O(n)

pattern: Linear scan

Ask these before you code:

  • Equal neighbours? "Non-decreasing" allows them. [1, 2, 2, 3] is sorted.
  • One item? Sorted. There is nothing to be out of order with.
  • Negative values? Fine. The comparison does not care about the sign.
  • Which direction? Increasing only. [3, 2, 1] is false.

n reaches 10⁶. One pass is 10⁶ steps, well inside the budget. A loop inside a loop would be about 5 × 10¹¹.

Brute force: compare every pair

Sorted means every value is at most every value after it. So check exactly that: for each i, compare arr[i] with every later value.

compare each value with every later valuecomparisons 5
2
0
4
1
4
2
7
3
5
4
9
5

1/4i = 0, value 2. Compare it with the 5 values after it. None is smaller.

13 comparisons to find one step down.
boolean isSorted(int[] arr) {
    for (int i = 0; i < arr.length; i++) {
        for (int j = i + 1; j < arr.length; j++) {
            if (arr[j] < arr[i]) return false;
        }
    }
    return true;
}

Count it out loud. The worst case is an array that is sorted, because the loops never stop early.

  • The outer loop runs n times.
  • The inner loop runs n − 1, then n − 2, and so on.
  • That adds up to n × (n − 1) / 2, so O(n²).

For n = 10⁶, that is about 5 × 10¹¹ comparisons. Far too slow.

The key insight: neighbours are enough

If 2 ≤ 4 and 4 ≤ 7, then 2 ≤ 7. You never need to compare 2 with 7 directly. Order carries along the chain.

So an array is sorted when every value is at least the one right before it. One step down anywhere breaks it.

Sorted means the bars never step down. Check each neighbour pair to find a drop.

The brute force repeats this work: it compares 2 with 7, 5 and 9, even though the neighbour checks already cover them.

Optimal: one pass over neighbours

  1. Start at i = 1, so there is always a value before it.
  2. If arr[i] is smaller than arr[i - 1], return false.
  3. If the loop ends, every pair was in order. Return true.

The same example, the same step down:

compare each value with the one before itcomparisons 1
2
0
4
1
4
2
7
3
5
4
9
5

1/44 is at least 2. In order.

4 comparisons instead of 13. A sorted array of n items takes n − 1.
boolean isSorted(int[] arr) {
    for (int i = 1; i < arr.length; i++) {
        if (arr[i] < arr[i - 1]) return false; // a step down breaks the order
    }
    return true;
}
  • Invariant: when the loop reaches i, everything before i is in order.
  • Time: at most n − 1 comparisons, so O(n). Space: O(1).
  • One item: the loop never runs, so the answer is true.

Side by side

ApproachIdeaTimeExtra spaceFits n = 10⁶?
Every paircompare each value with all later onesO(n²)O(1)no
Sort a copysort, then compare with the originalO(n log n)O(n)yes, but wasteful
Neighbourscompare each value with the one beforeO(n)O(1)yes

The middle row works (in TypeScript, only with (a, b) => a - b). But it sorts the whole array to answer a yes-or-no question.

Reverse in place: two pointers

"Reverse an array" adds a rule: change the array itself, with no second array.

Use two pointers. left starts at the first item and right at the last. Swap them, then move both toward the middle.

Swap the ends, step inward, stop when the pointers meet.
void reverseInPlace(int[] arr) {
    int left = 0;
    int right = arr.length - 1;
    while (left < right) {
        int temp = arr[left]; // swap the two ends
        arr[left] = arr[right];
        arr[right] = temp;
        left++;
        right--;
    }
}
  • n / 2 swaps, so O(n) time and O(1) extra space.
  • An odd length leaves the middle item where it is. One item or an empty array: the loop never runs.
  • Java swaps through a temp variable. Python and TypeScript swap both values in one line.
  • Each language has a built-in: Collections.reverse(list) in Java (not for int[]), arr.reverse() in Python and TypeScript. In an interview, write the loop.

How to spot this pattern

Signal in the problemWhat to reach for
"sum", "count", "largest" of the arrayone pass with a running answer
"is it sorted", "in order"compare each value with the one before
"reverse", "in place", "O(1) extra space"two pointers from both ends
n up to 10⁶ or moreanything slower than O(n log n) fails

The linear scan template:

int answer = 0; // the answer for the items seen so far
for (int i = 0; i < arr.length; i++) {
    // update answer from arr[i], or stop early
}

You will meet two pointers again soon, for moving zeros and removing duplicates in the Arrays chapter.

take U forwardYouTube
Arrays Intro Video, from Check if the array is sorted: Strivers A2Z DSA Course
Remember4 points
  1. 01

    Order carries along a chain, so checking each neighbour pair proves the whole array is sorted. That turns O(n²) into O(n).

  2. 02

    A linear scan keeps one running answer for the items seen so far: a sum, a count, a flag.

  3. 03

    To reverse in place, swap the two ends and walk two pointers to the middle: n / 2 swaps, no extra array.

  4. 04

    Edge cases: one item, equal neighbours, negative odd numbers (-3 % 2 is -1 in Java and TypeScript).

Read more

Next: counting with a hash map, to answer "how many times?" in one pass.

Practice

Solve these on the sheet after the lesson. Try each one for 20 minutes before you open its solution.

Striver's A2Z sheet0/5 solved
Open the sheet