DSA — Arrays & Strings

Essential array and string algorithms with JavaScript — Two Sum, Sliding Window, Kadane's, Anagrams, and more

Last updated on

Arrays and strings are the most common DSA interview topics. These patterns solve 80% of array/string problems.

Pattern 1: Two Pointers

Two Sum (Sorted Array)

function twoSum(nums, target) {
  let left = 0, right = nums.length - 1;

  while (left < right) {
    const sum = nums[left] + nums[right];
    if (sum === target) return [left, right];
    if (sum < target) left++;
    else right--;
  }
  return [-1, -1];
}

Two Sum (Unsorted — Hash Map)

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 [-1, -1];
}

// Time: O(n), Space: O(n)

Pattern 2: Sliding Window

Maximum Sum Subarray of Size K

function maxSumSubarray(arr, k) {
  let windowSum = 0;
  let maxSum = -Infinity;

  for (let i = 0; i < arr.length; i++) {
    windowSum += arr[i];

    if (i >= k - 1) {
      maxSum = Math.max(maxSum, windowSum);
      windowSum -= arr[i - (k - 1)]; // shrink window
    }
  }

  return maxSum;
}

Longest Substring Without Repeating Characters

function lengthOfLongestSubstring(s) {
  const seen = new Map(); // char → last index
  let maxLen = 0;
  let start = 0;

  for (let end = 0; end < s.length; end++) {
    if (seen.has(s[end]) && seen.get(s[end]) >= start) {
      start = seen.get(s[end]) + 1;
    }
    seen.set(s[end], end);
    maxLen = Math.max(maxLen, end - start + 1);
  }

  return maxLen;
}

// "abcabcbb" → 3 ("abc")
// Time: O(n), Space: O(min(n, alphabet))

Pattern 3: Kadane's Algorithm

Maximum Subarray Sum

function maxSubArray(nums) {
  let currentMax = nums[0];
  let globalMax = nums[0];

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

  return globalMax;
}

// [-2, 1, -3, 4, -1, 2, 1, -5, 4] → 6 (subarray [4, -1, 2, 1])
// Time: O(n), Space: O(1)

Pattern 4: Prefix Sum

function prefixSum(arr) {
  const prefix = [0];
  for (let i = 0; i < arr.length; i++) {
    prefix.push(prefix[i] + arr[i]);
  }
  return prefix;
}

// Range sum query: sum from index i to j
function rangeSum(prefix, i, j) {
  return prefix[j + 1] - prefix[i];
}

Pattern 5: Frequency Counter

function isAnagram(s, t) {
  if (s.length !== t.length) return false;

  const freq = {};
  for (const char of s) {
    freq[char] = (freq[char] || 0) + 1;
  }
  for (const char of t) {
    if (!freq[char]) return false;
    freq[char]--;
  }

  return true;
}

// isAnagram("listen", "silent") → true
// Time: O(n), Space: O(n)

String Problems

Palindrome Check

function isPalindrome(s) {
  const clean = s.toLowerCase().replace(/[^a-z0-9]/g, "");
  let left = 0, right = clean.length - 1;

  while (left < right) {
    if (clean[left] !== clean[right]) return false;
    left++;
    right--;
  }
  return true;
}

String Reversal

const reverse = (s) => [...s].reverse().join("");

// Without built-in
function reverseString(s) {
  let result = "";
  for (let i = s.length - 1; i >= 0; i--) {
    result += s[i];
  }
  return result;
}

JavaScript-Specific Tricks

// Remove duplicates
const unique = [...new Set(arr)];

// Frequency counter with Map
const freq = new Map();
for (const x of arr) freq.set(x, (freq.get(x) || 0) + 1);

// Sort numbers correctly
arr.sort((a, b) => a - b);

// Quick array of 0s
new Array(n).fill(0);

// 2D array
Array.from({ length: rows }, () => new Array(cols).fill(0));

On this page