You are given a string message and a positive integer limit.
You must splitmessage into one or more parts based on limit. Each resulting part should have the suffix "<a/b>", where "b" is to be replaced with the total number of parts and "a" is to be replaced with the index of the part, starting from 1 and going up to b. Additionally, the length of each resulting part (including its suffix) should be equal tolimit, except for the last part whose length can be at mostlimit.
The resulting parts should be formed such that when their suffixes are removed and they are all concatenated in order, they should be equal to message. Also, the result should contain as few parts as possible.
Return the parts message would be split into as an array of strings. If it is impossible to split message as required, return an empty array.
Input & Output
Example 1 — Basic Split
$Input:message = "this is really a long text", limit = 16
›Output:["this is re<1/3>", "ally a long<2/3>", " text<3/3>"]
💡 Note:Split into 3 parts: Part 1 has 10 chars + 6 char suffix = 16 total. Part 2 has 11 chars + 6 char suffix = 17 ≤ 16? No, this would be invalid. Let me recalculate: we need exactly 16 chars per part except the last.
Example 2 — Impossible Split
$Input:message = "short", limit = 15
›Output:[]
💡 Note:Cannot split because even with 1 part, "short<1/1>" would be 5 + 6 = 11 chars, but we need exactly 15 chars in each part except the last.
Example 3 — Edge Case Single Part
$Input:message = "ab", limit = 5
›Output:["ab<1/1>"]
💡 Note:Single part: "ab" (2 chars) + "<1/1>" (5 chars) = 7 total, but limit is 5, so this is actually impossible. Let me reconsider the problem constraints.
Constraints
1 ≤ message.length ≤ 104
1 ≤ limit ≤ 104
Visualization
Tap to expand
Understanding the Visualization
1
Input
Message and character limit per part
2
Process
Split message into minimum parts with suffixes <a/b>
3
Output
Array of parts, each ≤ limit length (except last can be shorter)
Key Takeaway
🎯 Key Insight: The suffix length depends on total parts count, requiring us to try different part counts to minimize splits
The key insight is that the suffix length depends on the total number of parts, so we must try different part counts to find the minimum valid split. The optimal approach uses enumeration or binary search to find the minimum number of parts, then validates if the message can be split accordingly. Time: O(b × n), Space: O(n).
Common Approaches
Approach
Time
Space
Notes
✓
Binary Search on Answer
O(log n × n)
O(n)
Use binary search to find the minimum number of parts needed
Brute Force Enumeration
O(b × n)
O(n)
Try every possible number of parts from 1 upward until we find a valid split
Binary Search on Answer — Algorithm Steps
Step 1: Set search range from 1 to message.length parts
Step 2: For mid value, check if message can be split into mid parts
Step 3: If possible, search left half; otherwise search right half
Step 4: Build and return the actual split for the minimum valid parts
Visualization
Tap to expand
Step-by-Step Walkthrough
1
Search Range
Set left=1, right=message.length
2
Test Middle
Check if mid parts can accommodate the message
3
Narrow Range
Adjust search range based on feasibility
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
bool canSplit(char* message, int limit, int parts) {
// Check if we can split message into 'parts' number of parts
char sampleSuffix[50];
sprintf(sampleSuffix, "<%d/%d>", parts, parts);
int suffixLen = strlen(sampleSuffix);
if (suffixLen >= limit) {
return false;
}
int availableSpace = limit - suffixLen;
long long totalAvailable = (long long)availableSpace * (parts - 1) + (limit - suffixLen);
return totalAvailable >= strlen(message);
}
char** buildSplit(char* message, int limit, int parts, int* returnSize) {
// Actually build the split with 'parts' number of parts
int n = strlen(message);
char sampleSuffix[50];
sprintf(sampleSuffix, "<%d/%d>", parts, parts);
int suffixLen = strlen(sampleSuffix);
int availableSpace = limit - suffixLen;
char** result = (char**)malloc(parts * sizeof(char*));
int pos = 0;
*returnSize = 0;
for (int i = 1; i <= parts; i++) {
char suffix[50];
sprintf(suffix, "<%d/%d>", i, parts);
result[i-1] = (char*)malloc((limit + 1) * sizeof(char));
if (i == parts) { // Last part
int remainingLen = n - pos;
if (remainingLen + strlen(suffix) > limit) {
// Free allocated memory
for (int j = 0; j < i; j++) {
free(result[j]);
}
free(result);
return NULL;
}
strncpy(result[i-1], message + pos, remainingLen);
result[i-1][remainingLen] = '\0';
strcat(result[i-1], suffix);
(*returnSize)++;
} else {
int charsToTake = (availableSpace < n - pos) ? availableSpace : n - pos;
strncpy(result[i-1], message + pos, charsToTake);
result[i-1][charsToTake] = '\0';
strcat(result[i-1], suffix);
pos += charsToTake;
(*returnSize)++;
}
}
if (pos == n) {
return result;
}
// Free memory if failed
for (int j = 0; j < *returnSize; j++) {
free(result[j]);
}
free(result);
*returnSize = 0;
return NULL;
}
char** solution(char* message, int limit, int* returnSize) {
int n = strlen(message);
*returnSize = 0;
// Binary search for minimum number of parts
int left = 1, right = n + 1;
int minParts = -1;
while (left <= right) {
int mid = (left + right) / 2;
if (canSplit(message, limit, mid)) {
minParts = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
if (minParts == -1) {
return NULL;
}
return buildSplit(message, limit, minParts, returnSize);
}
int main() {
char message[1000];
fgets(message, sizeof(message), stdin);
message[strcspn(message, "\n")] = 0; // Remove newline
int limit;
scanf("%d", &limit);
int returnSize;
char** result = solution(message, limit, &returnSize);
// Format output as JSON array
printf("[");
for (int i = 0; i < returnSize; i++) {
if (i > 0) printf(",");
printf("\"%s\"", result[i]);
free(result[i]);
}
printf("]\n");
if (result) free(result);
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
O(log n × n)
Binary search O(log n) iterations, each requiring O(n) validation
n
2n
⚡ Linearithmic
Space Complexity
O(n)
Store the result array containing message characters
n
2n
⚡ Linearithmic Space
12.4K Views
MediumFrequency
~35 minAvg. Time
285 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.