DEV Community

Cover image for Master Arrays in 25 Problems: From Novice to Expert
Akhilesh
Akhilesh

Posted on

Master Arrays in 25 Problems: From Novice to Expert

The complete roadmap to dominate array-based coding interviews

Arrays are the foundation of data structures. Master them, and you'll have the pattern recognition needed to solve 40% of all coding interview problems. This guide covers 25 essential problems with both brute force and optimal solutions explained in simple terms.

Why Arrays Matter
Arrays appear everywhere in technical interviews because they test:

  • Algorithm optimization - Can you improve from O(n²) to O(n)?
  • Space-time trade-offs - When to use extra memory for speed
  • Edge case handling - Empty arrays, single elements, duplicates
  • Pattern recognition - Identifying when to use specific techniques

Core Patterns

  1. Two Pointer Technique When to use: Finding pairs, removing duplicates, sorted arrays
// Template
let left = 0, right = array.length - 1;
while (left < right) {
    // Process elements at left and right
    // Move pointers based on condition
}
Enter fullscreen mode Exit fullscreen mode
  1. Sliding Window When to use: Subarrays, consecutive elements, "size k" problems
// Template
let windowStart = 0;
for (let windowEnd = 0; windowEnd < array.length; windowEnd++) {
    // Expand window
    // Shrink window when needed
}
Enter fullscreen mode Exit fullscreen mode
  1. HashMap for O(1) Lookup When to use: Finding complements, counting frequencies
// Template
const map = new Map();
for (let element of array) {
    if (map.has(target - element)) return true;
    map.set(element, index);
}
Enter fullscreen mode Exit fullscreen mode
  1. Prefix Sum When to use: Range queries, subarray sums
// Template
const prefix = [0];
for (let i = 0; i < array.length; i++) {
    prefix[i + 1] = prefix[i] + array[i];
}
// Range sum [left, right] = prefix[right + 1] - prefix[left]
Enter fullscreen mode Exit fullscreen mode

Problem Solutions

Problem 1: Two Sum
Difficulty: Easy | Platform: LeetCode #1
Problem Statement:
Given an array of integers and a target, return indices of two numbers that add up to target.

Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Explanation: nums[0] + nums[1] = 2 + 7 = 9
Enter fullscreen mode Exit fullscreen mode

Brute Force Approach:

function twoSum(nums, target) {
    for (let i = 0; i < nums.length; i++) {
        for (let j = i + 1; j < nums.length; j++) {
            if (nums[i] + nums[j] === target) {
                return [i, j];
            }
        }
    }
    return [];
}

// Time: O(n²) - Nested loops
// Space: O(1) - No extra space
Enter fullscreen mode Exit fullscreen mode

Why brute force fails: For 10,000 elements, this makes 50 million comparisons!
Optimal Solution - HashMap:

function twoSum(nums, target) {
    const map = new Map();

    for (let i = 0; i < nums.length; i++) {
        const complement = target - nums[i];

        if (map.has(complement)) {
            return [map.get(complement), i];
        }

        map.set(nums[i], i);
    }

    return [];
}

// Time: O(n) - Single pass
// Space: O(n) - HashMap storage
Enter fullscreen mode Exit fullscreen mode

Key Insight: Instead of checking all pairs, remember what we've seen and look for complements.
Pattern: HashMap for complement finding

Problem 2: Best Time to Buy and Sell Stock
Difficulty: Easy | Platform: LeetCode #121
Problem Statement:
Find maximum profit from buying and selling stock once.

Input: prices = [7,1,5,3,6,4]
Output: 5
Explanation: Buy at 1, sell at 6, profit = 5
Enter fullscreen mode Exit fullscreen mode

Brute Force Approach:

function maxProfit(prices) {
    let maxProfit = 0;

    for (let buy = 0; buy < prices.length; buy++) {
        for (let sell = buy + 1; sell < prices.length; sell++) {
            const profit = prices[sell] - prices[buy];
            maxProfit = Math.max(maxProfit, profit);
        }
    }

    return maxProfit;
}

// Time: O(n²)
// Space: O(1)
Enter fullscreen mode Exit fullscreen mode

Optimal Solution - Track Minimum:

function maxProfit(prices) {
    let minPrice = Infinity;
    let maxProfit = 0;

    for (let price of prices) {
        minPrice = Math.min(minPrice, price);
        maxProfit = Math.max(maxProfit, price - minPrice);
    }

    return maxProfit;
}

// Time: O(n) - Single pass
// Space: O(1)
Enter fullscreen mode Exit fullscreen mode

Key Insight: Track the minimum price seen so far, calculate profit at each step.
Pattern: Tracking extremes while iterating

Problem 3: Contains Duplicate
Difficulty: Easy | Platform: LeetCode #217
Problem Statement:
Return true if any value appears at least twice.

Input: nums = [1,2,3,1]
Output: true

Input: nums = [1,2,3,4]
Output: false
Enter fullscreen mode Exit fullscreen mode

Brute Force:

function containsDuplicate(nums) {
    for (let i = 0; i < nums.length; i++) {
        for (let j = i + 1; j < nums.length; j++) {
            if (nums[i] === nums[j]) return true;
        }
    }
    return false;
}

// Time: O(n²)
Enter fullscreen mode Exit fullscreen mode

Better - Sorting:

function containsDuplicate(nums) {
    nums.sort((a, b) => a - b);

    for (let i = 0; i < nums.length - 1; i++) {
        if (nums[i] === nums[i + 1]) return true;
    }
    return false;
}

// Time: O(n log n) - Due to sorting
// Space: O(1)
Enter fullscreen mode Exit fullscreen mode

Optimal - Set:

function containsDuplicate(nums) {
    const seen = new Set();

    for (let num of nums) {
        if (seen.has(num)) return true;
        seen.add(num);
    }

    return false;
}

// Time: O(n)
// Space: O(n)
Enter fullscreen mode Exit fullscreen mode

// One-liner:
const containsDuplicate = (nums) => new Set(nums).size !== nums.length;
Key Insight: Sets automatically handle uniqueness.
Pattern: Using Set for duplicate detection

Problem 4: Product of Array Except Self
Difficulty: Medium | Platform: LeetCode #238
Problem Statement:
Return array where each element is the product of all other elements. Cannot use division!

Input: nums = [1,2,3,4]
Output: [24,12,8,6]
Enter fullscreen mode Exit fullscreen mode

Cannot Use (Division not allowed):

function productExceptSelf(nums) {
    const total = nums.reduce((acc, num) => acc * num, 1);
    return nums.map(num => total / num);
}
// ❌ Violates constraint, fails with zeros
Optimal - Prefix & Suffix Products:
javascriptfunction productExceptSelf(nums) {
    const n = nums.length;
    const result = new Array(n);

    // Left products
    result[0] = 1;
    for (let i = 1; i < n; i++) {
        result[i] = result[i - 1] * nums[i - 1];
    }

    // Right products
    let rightProduct = 1;
    for (let i = n - 1; i >= 0; i--) {
        result[i] *= rightProduct;
        rightProduct *= nums[i];
    }

    return result;
}

// Time: O(n)
// Space: O(1) - Output array doesn't count
Enter fullscreen mode Exit fullscreen mode

Visual Breakdown:
nums = [1,2,3,4]

After left products: [1,1,2,6]
After right products: [24,12,8,6]
Key Insight: Build products from left, then multiply with products from right.
Pattern: Prefix/Suffix technique

Problem 5: Maximum Subarray (Kadane's Algorithm)
Difficulty: Medium | Platform: LeetCode #53
Problem Statement:
Find the contiguous subarray with the largest sum.

Input: nums = [-2,1,-3,4,-1,2,1,-5,4]
Output: 6
Explanation: [4,-1,2,1] has sum = 6
Enter fullscreen mode Exit fullscreen mode

Brute Force:

function maxSubArray(nums) {
    let maxSum = -Infinity;

    for (let i = 0; i < nums.length; i++) {
        let currentSum = 0;
        for (let j = i; j < nums.length; j++) {
            currentSum += nums[j];
            maxSum = Math.max(maxSum, currentSum);
        }
    }

    return maxSum;
}

// Time: O(n²)
Enter fullscreen mode Exit fullscreen mode

Optimal - Kadane's Algorithm:

function maxSubArray(nums) {
    let maxSum = nums[0];
    let currentSum = nums[0];

    for (let i = 1; i < nums.length; i++) {
        currentSum = Math.max(nums[i], currentSum + nums[i]);
        maxSum = Math.max(maxSum, currentSum);
    }

    return maxSum;
}

// Time: O(n)
// Space: O(1)
Enter fullscreen mode Exit fullscreen mode

Key Insight: At each position, decide: start fresh or extend current subarray?

currentSum = Math.max(nums[i], currentSum + nums[i]);
// Translation: "Better to start new here, or keep building?"
Enter fullscreen mode Exit fullscreen mode

Pattern: Dynamic programming, optimal substructure

Problem 6: Move Zeroes
Difficulty: Easy | Platform: LeetCode #283
Problem Statement:
Move all zeros to end while maintaining relative order of non-zeros. Must be in-place!

Input: nums = [0,1,0,3,12]
Output: [1,3,12,0,0]
Enter fullscreen mode Exit fullscreen mode

Optimal - Two Pointers:

function moveZeroes(nums) {
    let writeIndex = 0;

    // Move all non-zeros to front
    for (let readIndex = 0; readIndex < nums.length; readIndex++) {
        if (nums[readIndex] !== 0) {
            nums[writeIndex] = nums[readIndex];
            writeIndex++;
        }
    }

    // Fill rest with zeros
    for (let i = writeIndex; i < nums.length; i++) {
        nums[i] = 0;
    }
}

// Time: O(n)
// Space: O(1)
Enter fullscreen mode Exit fullscreen mode

Swap Approach (Single Pass):

function moveZeroes(nums) {
    let lastNonZeroIndex = 0;

    for (let i = 0; i < nums.length; i++) {
        if (nums[i] !== 0) {
            [nums[lastNonZeroIndex], nums[i]] = [nums[i], nums[lastNonZeroIndex]];
            lastNonZeroIndex++;
        }
    }
}

// Time: O(n)
// Space: O(1)
Enter fullscreen mode Exit fullscreen mode

Pattern: Two-pointer in-place manipulation

Problem 7: Merge Sorted Array
Difficulty: Easy | Platform: LeetCode #88
Problem Statement:
Merge two sorted arrays in-place into the first array.

Input: nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
Output: [1,2,2,3,5,6]
Enter fullscreen mode Exit fullscreen mode

Optimal - Merge from End:

function merge(nums1, m, nums2, n) {
    let p1 = m - 1;      // Pointer for nums1
    let p2 = n - 1;      // Pointer for nums2
    let p = m + n - 1;   // Pointer for result position

    while (p2 >= 0) {
        if (p1 >= 0 && nums1[p1] > nums2[p2]) {
            nums1[p] = nums1[p1];
            p1--;
        } else {
            nums1[p] = nums2[p2];
            p2--;
        }
        p--;
    }
}

// Time: O(m + n)
// Space: O(1)
Enter fullscreen mode Exit fullscreen mode

Key Insight: Fill from the end to avoid overwriting elements.
Pattern: Two-pointer merge

Problem 8: Array Manipulation (HackerRank)
Problem Statement:
Given array of size n (all zeros), perform m operations. Each operation adds value k to range [a,b]. Return maximum value after all operations.

n = 5, operations = [[1,2,100], [2,5,100], [3,4,100]]
Output: 200
Enter fullscreen mode Exit fullscreen mode

Brute Force (Times Out):

function arrayManipulation(n, queries) {
    const arr = new Array(n + 1).fill(0);

    for (let [a, b, k] of queries) {
        for (let i = a; i <= b; i++) {
            arr[i] += k;
        }
    }

    return Math.max(...arr);
}

// Time: O(n × m) - Too slow!
Enter fullscreen mode Exit fullscreen mode

Optimal - Difference Array:

function arrayManipulation(n, queries) {
    const diff = new Array(n + 2).fill(0);

    // Mark range boundaries
    for (let [a, b, k] of queries) {
        diff[a] += k;
        diff[b + 1] -= k;
    }

    // Compute prefix sum and find max
    let max = 0;
    let current = 0;
    for (let i = 1; i <= n; i++) {
        current += diff[i];
        max = Math.max(max, current);
    }

    return max;
}

// Time: O(n + m)
// Space: O(n)
Enter fullscreen mode Exit fullscreen mode

Why This Works:

Instead of updating every element in range, mark boundaries
Use prefix sum to calculate actual values
This reduces O(n×m) to O(n+m)

Pattern: Difference array for range updates

Complete Problem List
LeetCode Easy

✅ Two Sum - #1
✅ Best Time to Buy Stock - #121
✅ Contains Duplicate - #217
✅ Maximum Subarray - #53
✅ Merge Sorted Array - #88
✅ Move Zeroes - #283
✅ Plus One - #66
✅ Find Missing Number - #268
✅ Single Number - #136
✅ Intersection of Arrays - #349
✅ Third Maximum Number - #414
✅ Find Disappeared Numbers - #448
✅ Majority Element - #169
✅ Remove Duplicates - #26
✅ Search Insert Position - #35
✅ Pascal's Triangle - #118

LeetCode Medium

✅ Product of Array Except Self - #238

HackerRank

✅ Arrays - DS
✅ 2D Array - DS
✅ Dynamic Array
✅ Left Rotation
✅ Sparse Arrays
✅ Array Manipulation
✅ Minimum Swaps 2
✅ New Year Chaos

Practice Roadmap
Week 1: Foundations
Day 1-2: Two Sum, Contains Duplicate

  • Master HashMap usage
  • Understand O(1) lookup

Day 3-4: Best Time to Buy Stock, Move Zeroes

  • Practice two-pointer technique
  • In-place manipulation

Day 5-7: Product Except Self, Maximum Subarray

  • Learn prefix/suffix patterns
  • Understand Kadane's algorithm

Week 2: Apply Patterns
Days 1-3: All Easy LeetCode problems

  • Build speed and confidence
  • Recognize patterns quickly

Days 4-7: HackerRank challenges

  • Different problem formats
  • Edge case handling

Week 3: Master Difficulty
Days 1-3: Array Manipulation, New Year Chaos

  • Handle complex problems
  • Optimize space/time

Days 4-7: Review and speed practice

  • Solve problems in < 20 minutes
  • Practice explaining solutions

Quick Reference Guide

Pattern When to Use Example Problem
Two Pointers Sorted arrays, finding pairs Two Sum II
Sliding Window Subarrays of fixed or variable size k Maximum Average Subarray
HashMap Finding complements or frequency counting Two Sum
Prefix Sum Range sum queries, cumulative sums Subarray Sum Equals K
Kadane's Algorithm Maximum subarray problems Maximum Subarray
Difference Array Efficient range updates Array Manipulation

Common Pitfalls

1.Off-by-one errors

// ❌ Wrong
for (let i = 0; i <= nums.length; i++)

// ✅ Correct
for (let i = 0; i < nums.length; i++)
Enter fullscreen mode Exit fullscreen mode

2.Not handling empty arrays

if (!nums || nums.length === 0) return 0;
Enter fullscreen mode Exit fullscreen mode

3.Integer overflow (in other languages, JavaScript handles this)

// Safe midpoint calculation
let mid = left + Math.floor((right - left) / 2);
Enter fullscreen mode Exit fullscreen mode

4.Modifying while iterating

// ❌ Don't modify array you're iterating
for (let num of nums) {
    nums.splice(0, 1); // Bad!
}
Enter fullscreen mode Exit fullscreen mode

Next Steps

  1. Practice daily - Solve at least 2 problems
  2. Time yourself - Aim for 20-30 minutes per problem
  3. Review patterns - Identify which pattern applies
  4. Explain out loud - Practice articulating your approach

If you found this helpful, please share and follow for the complete DSA series!

Top comments (0)