Design and implement a reference-counting garbage collector system that automatically manages object memory. Your implementation should:
1. Track references: Maintain reference counts for all objects
2. Detect zero references: Identify objects with no active references
3. Automatic cleanup: Free memory for unreferenced objects
4. Handle cycles: Deal with circular reference scenarios
Given a sequence of operations (create object, assign reference, remove reference), return the list of object IDs that should be garbage collected (freed from memory) at the end.
The key insight is implementing real-time reference counting where objects are immediately marked for garbage collection when their reference count drops to zero. The optimal approach uses hash maps to track object references and counts, updating them instantly during each operation rather than scanning the entire system. Time: O(n × m), Space: O(m²)
Common Approaches
✓
Brute Force Reference Tracking
⏱️ Time: O(n × m²)
Space: O(m²)
Process each operation and maintain object relationships. After every operation, scan all objects to count references and identify garbage candidates.
Real-Time Reference Counting
⏱️ Time: O(n × m)
Space: O(m²)
Maintain reference counts in real-time as operations are processed. Immediately identify and collect garbage objects when their reference count drops to zero.
Brute Force Reference Tracking — Algorithm Steps
Create objects and reference maps
Process each operation sequentially
After each operation, count all references
Mark objects with zero references as garbage
Visualization
Tap to expand
Step-by-Step Walkthrough
1
Process Operation
Execute CREATE, REF, UNREF, or DELETE command
2
Full System Scan
Count references for every single object in system
3
Mark Garbage
Objects with zero references added to garbage list
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_OBJECTS 1000
#define MAX_ID_LEN 20
#define MAX_OPS 1000
typedef struct {
char id[MAX_ID_LEN];
int refCount;
int isDeleted;
int exists;
} Object;
typedef struct {
char from[MAX_ID_LEN];
char to[MAX_ID_LEN];
int active;
} Reference;
char* solution(char operations[][100], int opCount, int* returnSize) {
static Object objects[MAX_OBJECTS];
static Reference references[MAX_OBJECTS * 10];
static char result[MAX_OBJECTS * MAX_ID_LEN];
int objCount = 0, refCount = 0;
memset(objects, 0, sizeof(objects));
memset(references, 0, sizeof(references));
for (int i = 0; i < opCount; i++) {
char cmd[20], id1[MAX_ID_LEN], id2[MAX_ID_LEN];
sscanf(operations[i], "%s %s %s", cmd, id1, id2);
if (strcmp(cmd, "CREATE") == 0) {
strcpy(objects[objCount].id, id1);
objects[objCount].refCount = 0;
objects[objCount].isDeleted = 0;
objects[objCount].exists = 1;
objCount++;
} else if (strcmp(cmd, "REF") == 0) {
strcpy(references[refCount].from, id1);
strcpy(references[refCount].to, id2);
references[refCount].active = 1;
refCount++;
// Increment reference count for target object
for (int j = 0; j < objCount; j++) {
if (strcmp(objects[j].id, id2) == 0 && !objects[j].isDeleted) {
objects[j].refCount++;
break;
}
}
} else if (strcmp(cmd, "UNREF") == 0) {
// Find and deactivate reference
for (int j = 0; j < refCount; j++) {
if (strcmp(references[j].from, id1) == 0 &&
strcmp(references[j].to, id2) == 0 && references[j].active) {
references[j].active = 0;
// Decrement reference count
for (int k = 0; k < objCount; k++) {
if (strcmp(objects[k].id, id2) == 0 && !objects[k].isDeleted) {
objects[k].refCount--;
break;
}
}
break;
}
}
} else if (strcmp(cmd, "DELETE") == 0) {
// Mark object as deleted and remove its references
for (int j = 0; j < objCount; j++) {
if (strcmp(objects[j].id, id1) == 0) {
objects[j].isDeleted = 1;
break;
}
}
// Remove all references from this object
for (int j = 0; j < refCount; j++) {
if (strcmp(references[j].from, id1) == 0 && references[j].active) {
references[j].active = 0;
for (int k = 0; k < objCount; k++) {
if (strcmp(objects[k].id, references[j].to) == 0 && !objects[k].isDeleted) {
objects[k].refCount--;
break;
}
}
}
}
}
}
// Find garbage objects
int resultCount = 0;
result[0] = '[';
int pos = 1;
for (int i = 0; i < objCount; i++) {
if (objects[i].exists && !objects[i].isDeleted && objects[i].refCount == 0) {
if (resultCount > 0) {
result[pos++] = ',';
}
result[pos++] = '"';
strcpy(&result[pos], objects[i].id);
pos += strlen(objects[i].id);
result[pos++] = '"';
resultCount++;
}
}
result[pos++] = ']';
result[pos] = '\0';
*returnSize = pos;
return result;
}
int main() {
char line[10000];
fgets(line, sizeof(line), stdin);
// Parse JSON array manually
char operations[MAX_OPS][100];
int opCount = 0;
char* start = strchr(line, '[');
char* end = strrchr(line, ']');
char* token = strtok(start + 1, ",");
while (token && opCount < MAX_OPS) {
// Remove quotes and whitespace
while (*token == ' ' || *token == '"') token++;
char* endQuote = strrchr(token, '"');
if (endQuote) *endQuote = '\0';
strcpy(operations[opCount], token);
opCount++;
token = strtok(NULL, ",");
}
int returnSize;
char* result = solution(operations, opCount, &returnSize);
printf("%s\n", result);
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
O(n × m²)
n operations × m objects scanned × m reference checks per scan
n
2n
✓ Linear Growth
Space Complexity
O(m²)
Hash maps storing object references and relationship graph
n
2n
✓ Linear Space
26.7K Views
MediumFrequency
~35 minAvg. Time
890 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.