Skip to content

Instantly share code, notes, and snippets.

@MarcAbonce
Last active August 12, 2025 00:43
Show Gist options
  • Select an option

  • Save MarcAbonce/f442dc85796f1bd4481f8c85dacb31a8 to your computer and use it in GitHub Desktop.

Select an option

Save MarcAbonce/f442dc85796f1bd4481f8c85dacb31a8 to your computer and use it in GitHub Desktop.
Minimum Moves for Alternating Balls Sequence ([πŸ€πŸ€β¬œβ¬œπŸ€β¬œ] ➑️ [πŸ€β¬œπŸ€β¬œπŸ€β¬œ])

Copyright (C) 2025 Marc Abonce Seguin

This document is licensed under CC BY-NC-SA 4.0 (Creative Commons Attribution-NonCommercial-ShareAlike).

This means that if you redistribute a copy or a modified version of this work,
YOU MUST PRESERVE THE COPYRIGHT NOTICE AND LICENSE ABOVE!

In practice this means that this should be helpful for you to study for a coding interview, but if you were to use this in an actual interview, you'd be obligated to disclose that you didn't write it yourself.

Also, there's NO WARRANTY!

Minimum Moves for Alternating Balls Sequence

Problem

You receive an array of buckets that are either empty or have a ball inside. πŸ—‘οΈπŸ€
You have to calculate the minimum number of times you'd have to move the balls to have them all in an alternating pattern, so that you have neither 2 adjacent balls nor 2 balls separated by more than 1 empty bucket. The ball pattern may not necessarily fill the entire array. If there is no solution, return -1.

For example:
[πŸ€β¬œπŸ€β¬œπŸ€] requires 0 moves to have a valid pattern.
[πŸ€πŸ€β¬œ] requires 1 move to end up with [πŸ€β¬œπŸ€].
[β¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€β¬œπŸ€β¬œβ¬œβ¬œβ¬œ] requires 0 moves, the empty padding doesn't matter.
[πŸ€β¬œβ¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€] requires 1 move, from the left-most ball towards the right like [β¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€β¬œπŸ€].
[πŸ€πŸ€β¬œπŸ€] is impossible, so -1 should be returned.

Notes:
You don't need to actually move the balls, just calculate the minimum number of moves.
Input array may be very large, with up to 100,000 values.

Solution

This is solved with a fixed-sized sliding window algorithm.

Once we have the total number of balls in the array, we can know if a solution is impossible if the number of balls is more than half the size of the array, e.g. [πŸ€πŸ€β¬œπŸ€] is impossible because there is no way to fit 3 balls in 4 slots in an alternating pattern.

With the total number of balls we can also get the hypothetical ideal pattern that we should be getting at the end. For example, for input [πŸ€β¬œβ¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€] or any other array with 3 balls, we already know that we're looking for a solution that contains [πŸ€β¬œπŸ€β¬œπŸ€] as a subarray. We don't know yet where exactly would this subarray be ideally located, for example [πŸ€β¬œπŸ€β¬œπŸ€β¬œβ¬œβ¬œβ¬œ], [β¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€β¬œπŸ€] and [β¬œβ¬œπŸ€β¬œπŸ€β¬œπŸ€β¬œβ¬œ] all look like valid solutions, but some of these require more balls to be moved than others. We have to figure out which solution requires the minimum amount of moves.

If we overlap this ideal pattern over each slot of the input array, we can compare them and see how many balls are missing to complete the solved pattern over each position.

For example:
With input array [β¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€πŸ€β¬œβ¬œβ¬œβ¬œβ¬œ]
the solution should include pattern [πŸ”ΌοΈβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈ] (where each πŸ”ΌοΈ should overlap with a ball) so we iterate that pattern as a sliding window to get the minimum difference.

β¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€πŸ€β¬œβ¬œβ¬œβ¬œβ¬œ
πŸ”ΌοΈβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈ
βŒβ¬œβŒβ¬œβœ…
diff: 2

β¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€πŸ€β¬œβ¬œβ¬œβ¬œβ¬œ
β¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈ
⬜❌⬜❌⬜❌
diff: 3

β¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€πŸ€β¬œβ¬œβ¬œβ¬œβ¬œ
β¬œβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈ
β¬œβ¬œβŒβ¬œβœ…β¬œβœ…
diff: 1

β¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€πŸ€β¬œβ¬œβ¬œβ¬œβ¬œ
β¬œβ¬œβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈ
β¬œβ¬œβ¬œβŒβ¬œβŒβ¬œβœ…
diff: 2

β¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€πŸ€β¬œβ¬œβ¬œβ¬œβ¬œ
β¬œβ¬œβ¬œβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈ
β¬œβ¬œβ¬œβ¬œβœ…β¬œβœ…β¬œβŒ
diff: 1

β¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€πŸ€β¬œβ¬œβ¬œβ¬œβ¬œ
β¬œβ¬œβ¬œβ¬œβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈ
β¬œβ¬œβ¬œβ¬œβ¬œβŒβ¬œβœ…β¬œβŒ
diff: 2

β¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€πŸ€β¬œβ¬œβ¬œβ¬œβ¬œ
β¬œβ¬œβ¬œβ¬œβ¬œβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈ
β¬œβ¬œβ¬œβ¬œβ¬œβ¬œβœ…β¬œβŒβ¬œβŒ
diff: 2

β¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€πŸ€β¬œβ¬œβ¬œβ¬œβ¬œ
β¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈ
β¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œβœ…β¬œβŒβ¬œβŒ
diff: 2

β¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€πŸ€β¬œβ¬œβ¬œβ¬œβ¬œ
β¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈ
⬜⬜⬜⬜⬜⬜⬜⬜❌⬜❌⬜❌
diff: 3

Minimum diff is also the minimum number of moves: 1

Complexity

Space complexity

A simple implementation would use O(m) space, where m is the number of balls in the array (or the length of the sliding window, which depends on the number of balls in the array).
This is because of the ideal pattern array that we use as our sliding window.

However, this can be improved to O(1) by removing the auxiliary ideal pattern array, which is technically unnecessary because once we know the number of balls, we can calculate the size of the ideal pattern and it will always have the same sequence.

Time complexity

The above implementation would have a time complexity of O(n*m) where n is the length of the input array and m is the number of balls in the array.
This is because the sliding window itself iterates the whole array once, but inside each iteration we count the diff between the ideal pattern and the actual array, which is a linear operation of the size of the ideal pattern.

Faster Solution

Time complexity can be reduced to O(n), or 3 linear loops in total, by not recalculating values in the nested loop.
The first loop is always needed to count the number of balls in the input array.
Then, instead of passing the sliding window once, one spot at the time, and recalculating the diff each time, we can iterate twice: once for even-numbered slots only and then for odd-numbered slots only.
This way, we don't have to compare the entire ideal pattern against the subarray every single time.
Instead, we only have to "forget" the previous left-most slot and compare the new right-most slot.

For example:

First we slide window over even-numbered indices, starting at index 0 and we calculate diff just like we did before:
β¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€πŸ€β¬œβ¬œπŸ€β¬œβ¬œπŸ€β¬œ
πŸ”ΌοΈβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈ
βŒβ¬œβŒβ¬œβœ…β¬œβœ…β¬œβŒ
diff: 3

Then we skip 2 slots at once.
We "remember" 4 of the previous overlapping values πŸ’‘, so we don't need to compare those again.
Instead, we only "forget" the previous left-most difference πŸ”₯
and add the new right-most difference πŸ”.

Old diff was 3, the previous left-most slot was different ❌ so we "forget" that difference (-1)
and we add the new right-most difference (+0 because ball was found where ideal pattern expected it βœ…).

β¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€πŸ€β¬œβ¬œπŸ€β¬œβ¬œπŸ€β¬œ
β¬œβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈ
πŸ”₯β¬œπŸ’‘β¬œπŸ’‘β¬œπŸ’‘β¬œπŸ’‘β¬œπŸ”
β¬œβ¬œβŒβ¬œβœ…β¬œβœ…β¬œβŒβ¬œβœ…
diff: 3 - 1 + 0 = 2

Same process as above.
Old diff was 2, the previous left-most slot was different ❌ so we "forget" that difference (-1)
and we add the new right-most difference (+1 because ball was not found where ideal pattern expected it ❌).

β¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€πŸ€β¬œβ¬œπŸ€β¬œβ¬œπŸ€β¬œ
β¬œβ¬œβ¬œβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈ
⬜⬜πŸ”₯β¬œπŸ’‘β¬œπŸ’‘β¬œπŸ’‘β¬œπŸ’‘β¬œπŸ”
β¬œβ¬œβ¬œβ¬œβœ…β¬œβœ…β¬œβŒβ¬œβœ…β¬œβŒ
diff: 2 - 1 + 1 = 2

Old diff was 2, the previous left-most slot matched the ideal pattern βœ…, so no difference to be "forgotten" (-0)
and we add the new right-most difference (+1 because ball was not found where ideal pattern expected it ❌).

β¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€πŸ€β¬œβ¬œπŸ€β¬œβ¬œπŸ€β¬œ
β¬œβ¬œβ¬œβ¬œβ¬œβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈβ¬œπŸ”ΌοΈ
⬜⬜⬜⬜πŸ”₯β¬œπŸ’‘β¬œπŸ’‘β¬œπŸ’‘β¬œπŸ’‘β¬œπŸ”
β¬œβ¬œβ¬œβ¬œβ¬œβ¬œβœ…β¬œβŒβ¬œβœ…β¬œβŒβ¬œβŒ
diff: 2 - 0 + 1 = 3

Then, we would have to repeat the same process by sliding the window through the odd-numbered indices, starting at index 1 and skipping 2 slots at once.

Test Cases

πŸ€β¬œ
Min moves: 0

β¬œπŸ€
Min moves: 0

πŸ€β¬œπŸ€
Min moves: 0

β¬œπŸ€β¬œ
Min moves: 0

πŸ€β¬œπŸ€β¬œπŸ€
Min moves: 0

β¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€β¬œπŸ€β¬œβ¬œβ¬œβ¬œ
Min moves: 0

πŸ€πŸ€β¬œ
Min moves: 1

β¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€πŸ€β¬œβ¬œβ¬œβ¬œβ¬œ
Min moves: 1

πŸ€β¬œπŸ€β¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€
Min moves: 2

β¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€β¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€β¬œπŸ€β¬œπŸ€πŸ€β¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€β¬œ
Min moves: 3

β¬œπŸ€β¬œπŸ€β¬œπŸ€β¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€β¬œπŸ€β¬œπŸ€
Min moves: 3

β¬œπŸ€β¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œπŸ€β¬œπŸ€β¬œπŸ€β¬œπŸ€β¬œ
Min moves: 1

πŸ€πŸ€β¬œπŸ€β¬œπŸ€πŸ€πŸ€β¬œβ¬œβ¬œ
Min moves: 4

πŸ€πŸ€β¬œπŸ€
Min moves: -1

πŸ€β¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œβ¬œπŸ€... (i.e. that entire sequence repeated 10,000 times)
Min moves: 16000

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment