767. Reorganize String
mediumAsked at AmazonGiven a string, rearrange so no two adjacent chars are the same, or return empty if impossible. Amazon asks this to test whether you reach for a max-heap of (count, char) and articulate the 'highest-count first' greedy.
By Alex Chen, Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in Amazon loops.
- Glassdoor (2026-Q1)— Amazon SDE II onsite reports cite this as the heap-based greedy round.
- Blind (2025-10)— Recurring Amazon interview problem.
Problem
Given a string s, rearrange the characters of s so that any two adjacent characters are not the same. Return any possible rearrangement of s or return "" if not possible.
Constraints
1 <= s.length <= 500s consists of lowercase English letters.
Examples
Example 1
s = "aab""aba"Example 2
s = "aaab"""Approaches
1. Max-heap of (count, char) (optimal)
Count chars. Push (count, char) into max-heap. Pop the top two each step; emit both; push back with count - 1 if still positive.
- Time
- O(n log k)
- Space
- O(k)
class MaxHeap {
constructor() { this.data = []; }
push(v) { this.data.push(v); this._up(this.data.length - 1); }
pop() { if (!this.data.length) return; const top = this.data[0]; const last = this.data.pop(); if (this.data.length) { this.data[0] = last; this._down(0); } return top; }
size() { return this.data.length; }
_up(i) { while (i > 0) { const p = (i - 1) >> 1; if (this.data[p][0] >= this.data[i][0]) break; [this.data[p], this.data[i]] = [this.data[i], this.data[p]]; i = p; } }
_down(i) { while (true) { const l = 2*i+1, r = 2*i+2; let best = i; if (l < this.data.length && this.data[l][0] > this.data[best][0]) best = l; if (r < this.data.length && this.data[r][0] > this.data[best][0]) best = r; if (best === i) break; [this.data[best], this.data[i]] = [this.data[i], this.data[best]]; i = best; } }
}
function reorganizeString(s) {
const counts = new Map();
for (const ch of s) counts.set(ch, (counts.get(ch) || 0) + 1);
for (const [ch, c] of counts) if (c > Math.ceil(s.length / 2)) return '';
const heap = new MaxHeap();
for (const [ch, c] of counts) heap.push([c, ch]);
const out = [];
while (heap.size() >= 2) {
const [c1, ch1] = heap.pop();
const [c2, ch2] = heap.pop();
out.push(ch1, ch2);
if (c1 - 1 > 0) heap.push([c1 - 1, ch1]);
if (c2 - 1 > 0) heap.push([c2 - 1, ch2]);
}
if (heap.size()) {
const [c, ch] = heap.pop();
if (c > 1) return '';
out.push(ch);
}
return out.join('');
}Tradeoff: Pop two at a time guarantees no immediate repeat. The early-exit check (any char count > ceil(n/2)) handles impossibility upfront.
2. Slot-filling (alternative)
Place the most-frequent char in even indices first (0, 2, 4, ...). Then fill the remaining chars in any order in odd indices (and the leftover even slots).
- Time
- O(n)
- Space
- O(n)
function reorganizeStringSlots(s) {
const counts = new Map();
for (const ch of s) counts.set(ch, (counts.get(ch) || 0) + 1);
let maxCh = '', maxCnt = 0;
for (const [ch, c] of counts) if (c > maxCnt) { maxCnt = c; maxCh = ch; }
if (maxCnt > Math.ceil(s.length / 2)) return '';
const result = new Array(s.length);
let idx = 0;
while (maxCnt-- > 0) { result[idx] = maxCh; idx += 2; }
counts.delete(maxCh);
for (const [ch, c] of counts) {
let remaining = c;
while (remaining > 0) {
if (idx >= s.length) idx = 1;
result[idx] = ch;
remaining--;
idx += 2;
}
}
return result.join('');
}Tradeoff: O(n) — beats the heap. Place the most-frequent char in even slots first to guarantee separation. Then fill the rest.
Amazon-specific tips
Amazon interviewers grade this on the impossibility check: if any char's count exceeds ceil(n/2), return empty immediately. State that upfront. Then offer either heap (general pattern) or slot-filling (O(n) but trickier). Both score the same; pick what you can write cleanly.
Common mistakes
- Forgetting the impossibility check — heap or slots will silently produce an invalid result.
- Popping one at a time from the heap (you must pop TWO to ensure no adjacent repeat).
- Off-by-one in the slot indices (most-frequent char goes in even slots 0, 2, 4, ...).
Follow-up questions
An interviewer at Amazon may pivot to one of these next:
- Task Scheduler (LC 621) — same heap pattern with cooldown.
- What if the cooldown were variable (different per char)?
- What if we needed minimal length (allowing dummy chars)?
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
Why is ceil(n/2) the cutoff?
If a char appears more than ceil(n/2) times, you can't separate every occurrence — at least two must be adjacent. With exactly ceil(n/2), they fit in alternating slots starting at index 0.
Heap or slots — which does Amazon prefer?
Both work. Heap is the general pattern that generalizes to Task Scheduler. Slot-filling is faster but problem-specific. Lead with whichever you can code cleanly.
Practice these live with InterviewChamp.AI
Drill Reorganize String and other Amazon interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.
Practice these live with InterviewChamp.AI →