Skip to content
DSA arrays 10 min read

Array Exercises: Answer Sheet & Worked Solutions

This is the answer sheet for the array exercises. Each solution gives the key idea, the optimal complexity, the code in all four languages (use the switcher), and common pitfalls. Try the problems first — then check your work here.

Q1. Reverse an array in place

Idea: Use two pointers — one at each end — and swap, moving them toward the middle. This touches each element once and uses no extra array.

Complexity: O(n) time, O(1) extra space.

void reverse(std::vector<int>& a) {
    int i = 0, j = (int)a.size() - 1;
    while (i < j) std::swap(a[i++], a[j--]);
}

Pitfall: Looping all the way to the end (instead of the middle) reverses twice and returns the original array. Stop when i >= j.

Q2. Find the maximum element

Idea: Track a running maximum in one pass. Decide an empty-array policy up front — here we treat it as an error / return a sentinel.

Complexity: O(n) time, O(1) space.

int maxElement(const std::vector<int>& a) {
    int best = a[0]; // assume non-empty (validate before calling)
    for (int x : a) best = std::max(best, x);
    return best;
}

Pitfall: Initializing best = 0 breaks on all-negative arrays. Initialize from the first element instead.

Q3. Sum of all elements

Idea: A single accumulation pass. Use a 64-bit accumulator if values can be large to avoid overflow.

Complexity: O(n) time, O(1) space.

long long sum(const std::vector<int>& a) {
    long long total = 0;
    for (int x : a) total += x;
    return total;
}

Q4. Two Sum

Idea: The brute force checks every pair — O(n²). Instead, walk once with a hash map of value → index. For each x, check whether target - x was already seen. This trades O(n) memory for O(n) time.

Complexity: O(n) time, O(n) space.

std::vector<int> twoSum(const std::vector<int>& nums, int target) {
    std::unordered_map<int, int> seen;
    for (int i = 0; i < (int)nums.size(); i++) {
        int need = target - nums[i];
        if (seen.count(need)) return {seen[need], i};
        seen[nums[i]] = i;
    }
    return {};
}

Pitfall: Storing the value before checking lets a single element pair with itself. Always check target - x first, then insert x.

Q5. Move zeros to the end

Idea: Keep a write pointer for the next non-zero slot. Scan once, copying non-zeros forward; fill the rest with zeros. This preserves order in O(n).

Complexity: O(n) time, O(1) space.

void moveZeros(std::vector<int>& a) {
    int write = 0;
    for (int x : a) if (x != 0) a[write++] = x;
    while (write < (int)a.size()) a[write++] = 0;
}

Q6. Maximum subarray sum (Kadane’s algorithm)

Idea: At each position decide: extend the current subarray, or start fresh from here. Track the best sum seen. The insight — a negative running sum can only hurt what follows, so drop it.

Complexity: O(n) time, O(1) space.

int maxSubArray(const std::vector<int>& a) {
    int best = a[0], cur = a[0];
    for (int i = 1; i < (int)a.size(); i++) {
        cur = std::max(a[i], cur + a[i]);
        best = std::max(best, cur);
    }
    return best;
}

Pitfall: Initializing best = 0 fails on all-negative arrays (the answer should be the largest single element). Seed both best and cur from a[0].


That’s the full answer sheet. Back to the array exercises or continue to linked lists.

Last updated June 25, 2026
Was this helpful?