You are playing a variation of the game Zuma. In this variation of Zuma, there is a single row of colored balls on a board, where each ball can be colored red 'R', yellow 'Y', blue 'B', green 'G', or white 'W'. You also have several colored balls in your hand.
Your goal is to clear all of the balls from the board. On each turn:
Pick any ball from your hand and insert it in between two balls in the row or on either end of the row.
If there is a group of three or more consecutive balls of the same color, remove the group of balls from the board.
If this removal causes more groups of three or more of the same color to form, then continue removing each group until there are none left.
If there are no more balls on the board, then you win the game.
Repeat this process until you either win or do not have any more balls in your hand.
Given a string board, representing the row of balls on the board, and a string hand, representing the balls in your hand, return the minimum number of balls you have to insert to clear all the balls from the board. If you cannot clear all the balls from the board using the balls in your hand, return -1.
Input & Output
Example 1 — Basic Clear
$Input:board = "RWWWRR", hand = "RB"
›Output:2
💡 Note:Insert B at position 1: RBWWWRR → RBWWWRR (no removal). Insert B at position 2: RBBWWWRR → R___WWWRR (BBB removed) → RWWWRR. Insert R at position 3: RWWRRRR → RWW___ (RRR removed) → RWW. Continue to clear remaining.
Example 2 — Impossible Case
$Input:board = "RWWWRR", hand = "WWBBRR"
›Output:-1
💡 Note:No matter how we insert the balls, we cannot clear all balls from the board with the given hand.
Example 3 — Already Clear
$Input:board = "", hand = "RWB"
›Output:0
💡 Note:Board is already empty, so no moves needed.
Constraints
1 ≤ board.length ≤ 16
0 ≤ hand.length ≤ 5
board and hand consist of characters 'R', 'Y', 'B', 'G', and 'W'
The initial row of balls on the board will not have any groups of three or more consecutive balls of the same color
The key insight is to use BFS with memoization to systematically explore all possible game states level by level, ensuring we find the minimum number of moves. The algorithm tries inserting each ball at each position, removes consecutive groups, and continues until the board is cleared. Best approach is BFS with memoization. Time: O(2^(n+m) × n²), Space: O(2^(n+m))
Common Approaches
✓
BFS with Memoization
⏱️ Time: O(2^(n+m) × n²)
Space: O(2^(n+m))
Use breadth-first search to explore all possible game states level by level, ensuring we find the minimum number of moves. Memoization prevents recomputing the same board-hand combination multiple times.
Brute Force Recursion
⏱️ Time: O(n! × m^n)
Space: O(n)
For each ball in hand, try inserting it at every possible position on the board. After insertion, remove consecutive groups of 3+ same colored balls and recursively solve the remaining problem.
BFS with Memoization — Algorithm Steps
Use BFS queue to track (board, hand, moves) states
For each state, try inserting each unique ball at each position
Remove consecutive groups after insertion
Use memoization to avoid duplicate states
Return moves when board becomes empty
Visualization
Tap to expand
Step-by-Step Walkthrough
1
Initial State
Start with board and hand in queue
2
BFS Expansion
Try all ball insertions at current level
3
Memoization
Skip already seen board-hand combinations
4
Find Minimum
Return when board becomes empty
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STATES 100000
#define MAX_LEN 200
static char memo[MAX_STATES][MAX_LEN * 2];
static int memoCount = 0;
typedef struct {
char board[MAX_LEN];
char hand[MAX_LEN];
int moves;
} State;
static State queue[MAX_STATES];
void removeConsecutive(char* s, char* result) {
char stack[MAX_LEN];
int counts[MAX_LEN];
int stackSize = 0;
int len = strlen(s);
for (int i = 0; i < len; i++) {
char c = s[i];
if (stackSize > 0 && stack[stackSize - 1] == c) {
counts[stackSize - 1] += 1;
} else {
stack[stackSize] = c;
counts[stackSize] = 1;
stackSize++;
}
}
int pos = 0;
for (int i = 0; i < stackSize; i++) {
if (counts[i] < 3) {
for (int j = 0; j < counts[i]; j++) {
result[pos++] = stack[i];
}
}
}
result[pos] = '\0';
if (strcmp(result, s) != 0) {
char temp[MAX_LEN];
strcpy(temp, result);
removeConsecutive(temp, result);
}
}
int cmpchar(const void *a, const void *b) {
return (*(char*)a - *(char*)b);
}
int solution(char* board, char* hand) {
memoCount = 0;
int front = 0, rear = 0;
strcpy(queue[rear].board, board);
strcpy(queue[rear].hand, hand);
queue[rear].moves = 0;
rear++;
while (front < rear) {
State curr = queue[front];
front++;
if (strlen(curr.board) == 0) {
return curr.moves;
}
if (strlen(curr.hand) == 0) {
continue;
}
char sortedHand[MAX_LEN];
strcpy(sortedHand, curr.hand);
qsort(sortedHand, strlen(sortedHand), sizeof(char), cmpchar);
char state[MAX_LEN * 2];
sprintf(state, "%s,%s", curr.board, sortedHand);
int found = 0;
for (int i = 0; i < memoCount; i++) {
if (strcmp(memo[i], state) == 0) {
found = 1;
break;
}
}
if (found) {
continue;
}
if (memoCount < MAX_STATES) {
strcpy(memo[memoCount], state);
memoCount++;
}
// Try each unique ball in hand
char handSet[MAX_LEN];
int handSetSize = 0;
int handLen = strlen(curr.hand);
for (int h = 0; h < handLen; h++) {
char ball = curr.hand[h];
int exists = 0;
for (int k = 0; k < handSetSize; k++) {
if (handSet[k] == ball) {
exists = 1;
break;
}
}
if (!exists) {
handSet[handSetSize] = ball;
handSetSize++;
}
}
for (int h = 0; h < handSetSize; h++) {
char ball = handSet[h];
char newHand[MAX_LEN];
int pos = 0;
int removed = 0;
for (int i = 0; i < handLen; i++) {
if (curr.hand[i] == ball && !removed) {
removed = 1;
} else {
newHand[pos] = curr.hand[i];
pos++;
}
}
newHand[pos] = '\0';
// Try inserting at each position
int boardLen = strlen(curr.board);
for (int i = 0; i <= boardLen; i++) {
char newBoard[MAX_LEN];
strncpy(newBoard, curr.board, i);
newBoard[i] = ball;
strcpy(newBoard + i + 1, curr.board + i);
char cleanedBoard[MAX_LEN];
removeConsecutive(newBoard, cleanedBoard);
if (rear < MAX_STATES) {
strcpy(queue[rear].board, cleanedBoard);
strcpy(queue[rear].hand, newHand);
queue[rear].moves = curr.moves + 1;
rear++;
}
}
}
}
return -1;
}
int main() {
char inputLines[10][MAX_LEN];
int lineCount = 0;
while (lineCount < 10 && fgets(inputLines[lineCount], sizeof(inputLines[lineCount]), stdin)) {
inputLines[lineCount][strcspn(inputLines[lineCount], "\n")] = 0;
// Remove trailing whitespace
int len = strlen(inputLines[lineCount]);
while (len > 0 && (inputLines[lineCount][len-1] == ' ' || inputLines[lineCount][len-1] == '\t' || inputLines[lineCount][len-1] == '\r')) {
inputLines[lineCount][len-1] = '\0';
len--;
}
lineCount++;
}
char board[MAX_LEN], hand[MAX_LEN];
if (lineCount >= 2) {
strcpy(board, inputLines[0]);
strcpy(hand, inputLines[1]);
} else if (lineCount == 1) {
strcpy(board, inputLines[0]);
strcpy(hand, "");
} else {
strcpy(board, "");
strcpy(hand, "");
}
printf("%d\n", solution(board, hand));
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
O(2^(n+m) × n²)
BFS explores up to 2^(n+m) states, each requiring O(n²) processing for removal
n
2n
⚠ Quadratic Growth
Space Complexity
O(2^(n+m))
Memoization stores up to 2^(n+m) different board-hand combinations
n
2n
⚡ Linearithmic Space
28.4K Views
MediumFrequency
~35 minAvg. Time
856 Likes
Ln 1, Col 1
Smart Actions
💡Explanation
AI Ready
💡 SuggestionTabto acceptEscto dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen
Algorithm Visualization
Pinch to zoom • Tap outside to close
Test Cases
0 passed
0 failed
3 pending
Select Compiler
Choose a programming language
Compiler list would appear here...
AI Editor Features
Header Buttons
💡
Explain
Get a detailed explanation of your code. Select specific code or analyze the entire file. Understand algorithms, logic flow, and complexity.
🔧
Fix
Automatically detect and fix issues in your code. Finds bugs, syntax errors, and common mistakes. Shows you what was fixed.
💡
Suggest
Get improvement suggestions for your code. Best practices, performance tips, and code quality recommendations.
💬
Ask AI
Open an AI chat assistant to ask any coding questions. Have a conversation about your code, get help with debugging, or learn new concepts.
Smart Actions (Slash Commands)
🔧
/fix Enter
Find and fix issues in your code. Detects common problems and applies automatic fixes.
💡
/explain Enter
Get a detailed explanation of what your code does, including time/space complexity analysis.
🧪
/tests Enter
Automatically generate unit tests for your code. Creates comprehensive test cases.
📝
/docs Enter
Generate documentation for your code. Creates docstrings, JSDoc comments, and type hints.
⚡
/optimize Enter
Get performance optimization suggestions. Improve speed and reduce memory usage.
AI Code Completion (Copilot-style)
👻
Ghost Text Suggestions
As you type, AI suggests code completions shown in gray text. Works with keywords like def, for, if, etc.
Tabto acceptEscto dismiss
💬
Comment-to-Code
Write a comment describing what you want, and AI generates the code. Try: # two sum, # binary search, # fibonacci
💡
Pro Tip: Select specific code before using Explain, Fix, or Smart Actions to analyze only that portion. Otherwise, the entire file will be analyzed.