Skip to content
ΣDSA Patterns
Menu
Language

Difference Array

Guide 6 of 6 · Path 6 of 6

Demo preview: These solutions pass the automated test suite but have not been human-reviewed. Treat trade-offs and prose as draft.

Shifting Letters II

Problem (restated)

String s of lowercase letters. shifts[i]=[start,end,dir] shifts inclusive range forward (dir=1) or backward (dir=0) by 1. Return final string.

Intuition

Net shift per index via difference array; apply mod 26 to each character.

Approaches

Difference array of shift deltas

Tested only
Time O(n + q)Space O(n)

Idea. +1 or -1 on ranges; prefix sum is total shift; (c-‘a’+shift) mod 26.

Walkthrough. “abc”, [[0,1,0],[1,2,1],[0,2,1]] → “ace”.

Trade-offs. Naïve per-query update is O(nq); diff collapses to O(n+q).

Solution
export function shiftingLetters(s: string, shifts: number[][]): string {
  const n = s.length;
  const diff = Array(n + 1).fill(0);
  for (const sh of shifts) {
    const d = sh[2] === 1 ? 1 : -1;
    diff[sh[0]!] += d;
    diff[sh[1]! + 1] -= d;
  }
  const chars = s.split("");
  let cur = 0;
  for (let i = 0; i < n; i++) {
    cur += diff[i]!;
    let k = (chars[i]!.charCodeAt(0) - 97 + cur) % 26;
    if (k < 0) k += 26;
    chars[i] = String.fromCharCode(97 + k);
  }
  return chars.join("");
}
export function shiftingLetters(s: string, shifts: number[][]): string {
  const n = s.length;
  const diff = Array(n + 1).fill(0);
  for (const sh of shifts) {
    const d = sh[2] === 1 ? 1 : -1;
    diff[sh[0]!] += d;
    diff[sh[1]! + 1] -= d;
  }
  const chars = s.split("");
  let cur = 0;
  for (let i = 0; i < n; i++) {
    cur += diff[i]!;
    let k = (chars[i]!.charCodeAt(0) - 97 + cur) % 26;
    if (k < 0) k += 26;
    chars[i] = String.fromCharCode(97 + k);
  }
  return chars.join("");
}

Template connection

Difference array range updates on a string.

Reflection