Given a list of phrases, generate a list of Before and After puzzles.
A phrase is a string that consists of lowercase English letters and spaces only. No space appears in the start or the end of a phrase. There are no consecutive spaces in a phrase.
Before and After puzzles are phrases that are formed by merging two phrases where the last word of the first phrase is the same as the first word of the second phrase. Note that only the last word of the first phrase and the first word of the second phrase are merged in this process.
Return the Before and After puzzles that can be formed by every two phrases phrases[i] and phrases[j] where i != j. Note that the order of matching two phrases matters, we want to consider both orders.
You should return a list of distinct strings sorted lexicographically, after removing all duplicate phrases in the generated Before and After puzzles.
Input & Output
Example 1 — Basic Connection
$Input:phrases = ["writing code", "code review"]
›Output:["writing code review"]
💡 Note:The last word "code" of first phrase matches the first word "code" of second phrase. Merge by removing the duplicate: "writing code" + "review" = "writing code review"
The key insight is to recognize that we need to match last words with first words efficiently. The best approach uses hash maps to group phrases by their first and last words, enabling O(1) lookups instead of O(n²) comparisons. Time: O(n×m + k×m), Space: O(n×m) where n is phrases count, m is average phrase length, and k is result count.
Common Approaches
✓
Frequency Count
⏱️ Time: N/A
Space: N/A
Brute Force
⏱️ Time: O(n² × m)
Space: O(k × m)
For each pair of phrases, extract their first and last words. If the last word of the first phrase matches the first word of the second phrase, merge them by combining all words except the duplicate connecting word.
Hash Map Optimization
⏱️ Time: O(n × m + k × m)
Space: O(n × m)
Instead of checking every pair, group phrases by their first and last words using hash maps. For each phrase with last word W, quickly find all phrases starting with W using the hash map lookup.
Algorithm Steps — Algorithm Steps
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_PHRASES 100
#define MAX_LENGTH 1000
#define MAX_RESULTS 10000
static char phrases[MAX_PHRASES][MAX_LENGTH];
static char results[MAX_RESULTS][MAX_LENGTH];
static int result_count = 0;
// Extract first word from phrase
void getFirstWord(const char* phrase, char* first) {
int i = 0;
while (phrase[i] && phrase[i] != ' ') {
first[i] = phrase[i];
i++;
}
first[i] = '\0';
}
// Extract last word from phrase
void getLastWord(const char* phrase, char* last) {
int len = strlen(phrase);
int start = len - 1;
// Find start of last word
while (start >= 0 && phrase[start] != ' ') {
start--;
}
start++; // Move to first character of last word
strcpy(last, phrase + start);
}
// Get prefix (everything except last word)
void getPrefix(const char* phrase, char* prefix) {
int len = strlen(phrase);
int end = len - 1;
// Find end of prefix (before last word)
while (end >= 0 && phrase[end] != ' ') {
end--;
}
if (end >= 0) {
strncpy(prefix, phrase, end);
prefix[end] = '\0';
} else {
prefix[0] = '\0';
}
}
// Get suffix (everything except first word)
void getSuffix(const char* phrase, char* suffix) {
int i = 0;
// Skip first word
while (phrase[i] && phrase[i] != ' ') {
i++;
}
if (phrase[i] == ' ') {
strcpy(suffix, phrase + i + 1);
} else {
suffix[0] = '\0';
}
}
// Check if result already exists
int exists(const char* result) {
for (int i = 0; i < result_count; i++) {
if (strcmp(results[i], result) == 0) {
return 1;
}
}
return 0;
}
// Compare function for qsort
int compare(const void* a, const void* b) {
return strcmp((char*)a, (char*)b);
}
int main() {
char input[MAX_LENGTH];
fgets(input, sizeof(input), stdin);
// Parse JSON array of phrases
int phrase_count = 0;
char* ptr = input;
// Skip opening bracket and whitespace
while (*ptr && (*ptr == '[' || *ptr == ' ' || *ptr == '\n')) ptr++;
while (*ptr && *ptr != ']') {
if (*ptr == '"') {
ptr++; // Skip opening quote
int i = 0;
while (*ptr && *ptr != '"') {
phrases[phrase_count][i++] = *ptr++;
}
phrases[phrase_count][i] = '\0';
phrase_count++;
if (*ptr == '"') ptr++; // Skip closing quote
}
// Skip comma and whitespace
while (*ptr && (*ptr == ',' || *ptr == ' ')) ptr++;
}
// Find all before and after puzzles
for (int i = 0; i < phrase_count; i++) {
for (int j = 0; j < phrase_count; j++) {
if (i == j) continue;
char last_word[MAX_LENGTH], first_word[MAX_LENGTH];
getLastWord(phrases[i], last_word);
getFirstWord(phrases[j], first_word);
if (strcmp(last_word, first_word) == 0) {
char prefix[MAX_LENGTH], suffix[MAX_LENGTH];
char merged[MAX_LENGTH];
getPrefix(phrases[i], prefix);
getSuffix(phrases[j], suffix);
// Build merged phrase
if (strlen(prefix) > 0) {
strcpy(merged, prefix);
strcat(merged, " ");
strcat(merged, last_word);
} else {
strcpy(merged, last_word);
}
if (strlen(suffix) > 0) {
strcat(merged, " ");
strcat(merged, suffix);
}
if (!exists(merged)) {
strcpy(results[result_count], merged);
result_count++;
}
}
}
}
// Sort results
qsort(results, result_count, sizeof(results[0]), compare);
// Output results
printf("[");
for (int i = 0; i < result_count; i++) {
if (i > 0) printf(",");
printf("\"%s\"", results[i]);
}
printf("]\n");
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
n
2n
✓ Linear Growth
Space Complexity
n
2n
⚡ Linearithmic Space
18.5K Views
MediumFrequency
~25 minAvg. Time
487 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.