InterviewLegend

Arrays, Hashing & Strings

Alex Chen24 min readUpdated
In this lesson
  • Use a hash map for counting or a one-pass "have I seen this" lookup
  • Collapse repeated prefix work into one difference-array sweep, which the naive Shifting Letters loop misses
  • Write the Chewy way: correct first, then readable enough that a reviewer would approve it, then fast

Most Chewy loops start here. The online assessment is a HackerRank set, usually two problems in 50 to 90 minutes, and it stays in plain data structures and algorithms: arrays, hashing, strings, and the occasional tree. Nothing LeetCode-hard. Java is the default language on the platform, though Python and JavaScript are accepted. The bar is simpler than a FAANG gauntlet, and easy to underrate. Your solution has to work, it cannot be a mess, and you should not write it like you hate the person who reads it next.

Two ideas carry almost everything in this group. A hash map answers "how many times have I seen this" or "have I passed the value I need" in constant time, which kills nested-loop scans. And when a problem repeats the same prefix update over and over, a difference array turns all of that repeated work into one counting pass. Learn those two moves and the rest is bookkeeping the interviewer wants to see done cleanly.

How Chewy frames it

The HackerRank OA grades you against hidden test cases, so correctness is not a judgment call: your code passes or it does not. That changes what matters. There is no interviewer to award partial credit for a good idea, and there is no credit for a clever one-liner that fails an edge case. Read the constraints, handle the empty input and the single element, and get all the tests green. Reports describe a Two Sum variation as the classic opener, a Top-K question in the live screen, and a Shifting Letters style string transform where the obvious loop is too slow.

The live coding screen adds a second bar. An engineer is watching, and Chewy runs a separate debugging round where you fix broken code and write your own test cases. So the loop rewards the same instinct twice: name your data structure before you type, walk one input through by hand, and leave code a teammate could read. A working solution that a reviewer would send back for a rewrite is a weak signal even when the tests pass.

The Chewy angle
Chewy hires builders who ship, and it shows in how the code is judged. The graders care that the solution works, that it is not a tangle, and that it reads like you respected future-you. So spend the first minute stating the plan out loud, "I will count with a hash map, then read the buckets high to low." Name the edge cases before you write them: empty input, a single element, all-duplicate values. On the OA those cases are hidden tests you cannot see. In the live rounds, naming them is the Operate in the Details signal the interviewer is scoring.

Both templates trade a little memory for a single pass. A hash map remembers what you have already counted or seen, so you never rescan. A difference array remembers the edges of every range update, so you apply a hundred prefix bumps in one sweep instead of a hundred loops. When a problem says "count the most frequent," "find the pair," or "apply many overlapping updates," ask one question first. What would you have to remember to answer this in one pass? The answer is almost always one of these two.

The two templates to know

Nearly everything Chewy asks in this group is one of these two, or a small mix.

Pattern 1: Hash map for counting and one-pass lookup

A hash map (Python's dict) stores key-to-value pairs and looks any key up in roughly O(1) time. Two moves cover the group. For a lookup, you walk the array once and at each element ask the map a question it answers instantly, like "have I already seen the partner that completes this pair." For counting, you tally each value as you pass it, then read the tallies back. The Two Sum opener is the lookup form: remember every value's index, and the partner check becomes one query instead of a rescan.

python
def two_sum(nums, target):
seen = {} # value -> its index, filled as we go
for i, n in enumerate(nums):
need = target - n # the partner that would complete the pair
if need in seen: # O(1) question: have we passed 'need' already?
return [seen[need], i]
seen[n] = i # remember this value for a later element
return []

The brute force checks every pair in O(n squared). The map collapses that to O(n) by remembering each value the instant you pass it. The counting form uses the same structure with a different question. Instead of storing an index, you store a running total, which the Top-K problem below needs to rank values by frequency.

Pattern 2: Difference array for cheap range updates

Some problems ask you to add the same amount to a whole prefix or range of an array, many times over. Doing each update with a loop is O(range) per update, and stacked up that is O(n times m), which is what times out. A difference array records only where each range starts and ends: to add one to positions 0 through length - 1, you bump diff[0] up and diff[length] down. After every range is recorded, a single running sum over diff reconstructs the true value at each position.

python
def apply_range_adds(n, ranges):
diff = [0] * (n + 1) # one extra slot for the closing edge
for start, end in ranges: # add 1 to every index in [start, end]
diff[start] += 1 # the range opens here
diff[end + 1] -= 1 # and closes just after 'end'
result = []
running = 0
for i in range(n):
running += diff[i] # prefix sum rebuilds the real value
result.append(running)
return result

The whole idea is that a range update touches only two cells, not the whole range, so m updates cost O(m) to record and one O(n) sweep to resolve. That is the exact move the naive Shifting Letters loop misses: it re-walks a prefix on every shift and times out, while a difference array counts every shift in one pass.

State the structure out loud before you write a line. "I will count into a hash map" or "I will record range edges in a difference array" tells the interviewer you have seen the shape. It also gives you something to reason about on the OA before there is any code to debug. On the live screen it is also the readability signal Chewy scores: a named plan reads as an owner, a silent scramble does not.

Asked at Chewy

Three problems, drawn from what Chewy asks in this group: a string transform where the naive loop is too slow, a frequency ranking, and the easy that rounds out the OA pair. Read each spec twice, say your edge cases before you type, and keep the code readable enough to pass the debugging-round smell test.

The Chewy angle
Chewy pairs these with a second problem in the same sitting, so the first one is a clock. The OA typically bundles a medium with an easy or two mediums, and the live screen has put a Top-K question next to a practical class-design problem. Land the right structure fast, prove it on one input, and you bank minutes for the harder half. Sink the clock into a brute force you have to rewrite, and you have done the reverse of what Deliver Results rewards.
1

Top K Frequent Elements: Count, Then Bucket

MediumFrequently asked
Problem
Given an integer array nums and an integer k, return the k most frequent elements. You may return the answer in any order, and it is guaranteed to be unique.

Input: nums = [1,1,1,2,2,3], k = 2

Output: [1,2]

1 appears three times and 2 appears twice, the two highest counts.

Input: nums = [1], k = 1

Output: [1]

One element, one answer.

How this uses the pattern

Count every value with a hash map, then place each value into a bucket indexed by its frequency. Walk the buckets from the highest frequency down and take the first k values, which avoids a full sort.

Top K Frequent Elements: Count, Then Bucket

Loading...
Click "Run" to execute your code

Test Cases

Input: [[1,1,1,2,2,3], 2]Expected: [1,2]
Input: [[1], 1]Expected: [1]
Input: [[4,4,4,5,5,6,6,6,6], 2]Expected: [6,4]
Input: [[7,7,3,3,3,9,9,9,9,1], 2]Expected: [9,3]
The Chewy angle
Reports describe a Top-K variation as the live screen's algorithm question, often sitting next to a practical class-design problem in the same hour. Because it shares the slot, speed matters: reach for the O(n) count-then-bucket approach rather than a full sort, and say why. A frequency can never exceed the array length, so bucketing by count is bounded and clean, the readable move a Chewy reviewer wants to see.
Take it further
What if the array is enormous but k is small? Skip the buckets and keep a min-heap of size k keyed by frequency: push each value, and pop the smallest whenever the heap grows past k. You hold only k entries and the cost drops to O(n log k), which beats the O(n) bucket approach on memory when the number of distinct values is huge relative to k.
2

Shifting Letters: Count Prefix Updates

MediumCommonly asked
Problem
You are given a lowercase string s and an array shifts of positive integers. Process the shifts in order. For shift i, take the value shifts[i] and advance the first shifts[i] characters of the string by one letter each, wrapping z back to a. After all shifts are applied, return the final string.

For example, with s = "abcd" and shifts = [1, 2, 3, 4]: the first shift advances 1 character to get "bbcd", the next advances 2 characters to "cccd", then 3 to "dddd", then 4 to "eeee".

Input: s = "abcd", shifts = [1,2,3,4]

Output: "eeee"

Position 0 is inside all four prefixes so it advances 4 (a to e); position 3 is inside only the last prefix so it advances 1 (d to e).

Input: s = "aez", shifts = [1,1,3]

Output: "dfa"

a advances 3 to d, e advances 1 to f, z advances 1 and wraps to a.

Input: s = "abc", shifts = [2,2,2]

Output: "dec"

The first two characters sit in all three prefixes (+3), the third sits in none (+0).

How this uses the pattern

Do not re-walk a prefix per shift. Each shift of length L adds 1 to positions 0..L-1, which is a range update. Record the edges in a difference array, then one prefix sum gives the total advance for every position.

Shifting Letters: Count Prefix Updates

Loading...
Click "Run" to execute your code

Test Cases

Input: ["abcd", [1,2,3,4]]Expected: "eeee"
Input: ["aez", [1,1,3]]Expected: "dfa"
Input: ["abc", [2,2,2]]Expected: "dec"
Input: ["z", [1,1,1]]Expected: "c"
Input: ["hello", []]Expected: "hello"
The Chewy angle
This is the string transform where the obvious solution times out. The naive loop advances a prefix character by character on every shift, which is O(n times m) and hits the timeout on the hidden tests, exactly what one candidate reported. Chewy is watching whether you notice that "advance the first L characters" is a range update, not per-character work. Reframe it as counting how many shifts cover each position and the whole thing collapses to two linear passes.
Take it further
What if each shifts[i] is a shift amount applied to the first i + 1 characters, not a repeated +1? That is the standard library version of this problem. Now position j accumulates every shifts[i] with i >= j, so a suffix sum from the right gives each position's total advance in one pass. Same insight, one direction flipped: instead of counting how many ranges cover a spot, you sum the amounts that reach it.
3

Valid Parentheses: Match With a Stack

EasyCommonly asked
Problem
Given a string s containing only the characters ()[]{}, decide whether every bracket is closed by the matching type in the correct order. Return true if the string is valid and false otherwise. An empty string is valid.

Input: s = "()[]{}"

Output: true

Each opener is closed by its own type in order.

Input: s = "(]"

Output: false

A round opener is closed by a square bracket.

Input: s = "([)]"

Output: false

The brackets close in the wrong order even though the counts match.

How this uses the pattern

Push every opener onto a stack. On a closer, the top of the stack must be its matching opener, so pop and compare. Valid means the stack is empty at the end.

Valid Parentheses: Match With a Stack

Loading...
Click "Run" to execute your code

Test Cases

Input: "()"Expected: true
Input: "()[]{}"Expected: true
Input: "(]"Expected: false
Input: "([)]"Expected: false
Input: "{[]}"Expected: true
Input: ""Expected: true
Input: "]"Expected: false
The Chewy angle
This is the easy half of the OA pair, and it also turns up in the intern screen. It looks trivial, but Chewy still watches two edge cases. A closer can arrive with an empty stack, and openers can be left unclosed at the end. Handle both explicitly and narrate them, since the debugging round is built around exactly the boundaries people skip.
Take it further
What if you only had one bracket type, say ()? You would not need a stack at all: a single counter that increments on ( and decrements on ) works, is invalid the moment it goes negative, and must land at zero. The stack is what generalizes that counter to multiple types, because now you must remember which opener is still waiting, not just how many.

Key Takeaways

  • ✓The Chewy OA stays in plain arrays, hashing, and strings on HackerRank; correctness against hidden tests comes first, then readable code a reviewer would approve, then speed.
  • ✓A hash map answers "how many" and "have I seen it" in one pass, which powers both the Two Sum opener and the Top-K frequency ranking (count, then bucket by frequency for O(n)).
  • ✓When a problem repeats a prefix or range update, a difference array records only the edges and resolves them in one sweep. The naive Shifting Letters loop misses that reframe and times out.
  • ✓Name your structure and your edge cases before you type. Empty input, a single element, a leading closer, a full-length shift: those are the hidden tests on the OA and the traps the debugging round hands you on purpose.
Had your Chewy interview?Tell us what they asked. Reviewed before it goes in, never with your name.
Chewy interview guide

Know what Chewy asks before you walk in.

9 coding · 1 system design · 28 behavioral questions

Get Premium$49 a year · Cancel anytime
Or start freeNo card.

Get their questions first.

InterviewLegend is independent and not affiliated with or endorsed by any company it covers.