2796. Repeat String 🔒
Problem Description
The task is to extend the built-in String
prototype in TypeScript/JavaScript by adding a custom method called replicate(x)
. This method should take a number x
as an argument and return the original string repeated x
times.
For example:
- If you have the string
"hello"
and call"hello".replicate(3)
, it should return"hellohellohello"
- If you have the string
"ab"
and call"ab".replicate(4)
, it should return"abababab"
The key requirement is that you cannot use the built-in string.repeat()
method to implement this functionality. You need to find an alternative approach to achieve the string repetition.
The solution uses TypeScript's global declaration to extend the String
interface, then implements the method by creating an array of the specified size, filling it with the original string, and joining all elements together with an empty string delimiter. This effectively concatenates the string times
number of times without using the repeat()
method.
Intuition
Since we cannot use the built-in repeat()
method, we need to think of alternative ways to duplicate a string multiple times. The most straightforward approach would be to use a loop and concatenate the string to itself x
times, but there's a more elegant solution using array manipulation.
The key insight is that we can leverage JavaScript's array methods to achieve repetition. When we create an array with a specific length and fill it with the same value, we essentially have that value repeated multiple times in memory. The challenge then becomes how to convert this array of repeated strings back into a single concatenated string.
This leads us to the pattern: new Array(times).fill(this).join('')
new Array(times)
creates an array withtimes
empty slots.fill(this)
populates each slot with the current string (wherethis
refers to the string the method is called on).join('')
concatenates all array elements into a single string with no separator
For example, if we call "ab".replicate(3)
:
- We create an array of length 3:
[empty, empty, empty]
- Fill it with "ab":
["ab", "ab", "ab"]
- Join with empty separator:
"ababab"
This approach is concise and avoids manual loop construction or recursive calls, making it both readable and efficient for the task at hand.
Solution Approach
The implementation consists of two main parts: extending the TypeScript type system and implementing the actual method.
Step 1: Type Declaration
declare global {
interface String {
replicate(times: number): string;
}
}
This TypeScript declaration extends the global String
interface to include our new replicate
method. This tells TypeScript that all strings will have this method available, preventing type errors when we call it.
Step 2: Method Implementation
String.prototype.replicate = function (times: number) {
return new Array(times).fill(this).join('');
};
The implementation breaks down into three operations:
-
Array Creation:
new Array(times)
creates an array with a length equal to thetimes
parameter. Initially, this array contains empty slots. -
Array Filling:
.fill(this)
populates every position in the array with the current string value. In the context of a prototype method,this
refers to the string instance on which the method is called. -
String Concatenation:
.join('')
merges all array elements into a single string. By using an empty string''
as the separator, the strings are concatenated directly without any characters between them.
Example Walkthrough:
When calling "cat".replicate(3)
:
new Array(3)
→[empty, empty, empty]
.fill("cat")
→["cat", "cat", "cat"]
.join('')
→"catcatcat"
This approach efficiently handles edge cases:
- If
times
is 0, it creates an empty array, resulting in an empty string - If
times
is 1, it returns the original string - The method works for any positive integer value of
times
Ready to land your dream job?
Unlock your dream job with a 3-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through the solution with the example "hi".replicate(4)
:
Step 1: Method Call
When we call "hi".replicate(4)
, the method executes with this = "hi"
and times = 4
.
Step 2: Create Empty Array
new Array(4)
// Creates: [empty, empty, empty, empty]
We now have an array with 4 empty slots.
Step 3: Fill Array with String
[empty, empty, empty, empty].fill("hi") // Results in: ["hi", "hi", "hi", "hi"]
Each empty slot is replaced with our original string "hi".
Step 4: Join Array Elements
["hi", "hi", "hi", "hi"].join('') // Results in: "hihihihi"
The join('')
method concatenates all array elements with no separator between them.
Final Result: "hihihihi"
Edge Case Example: "test".replicate(0)
new Array(0)
creates an empty array[]
.fill("test")
has nothing to fill, remains[]
.join('')
on an empty array returns""
- Result: empty string
This demonstrates how the solution elegantly handles both normal cases and edge cases without explicit conditional logic.
Solution Implementation
1# Extend the built-in str class to include the replicate method
2class ExtendedString(str):
3 """
4 Extended string class that adds a replicate method to standard string functionality
5 """
6
7 def replicate(self, times: int) -> str:
8 """
9 Replicates the string a specified number of times
10
11 Args:
12 times: The number of times to replicate the string
13
14 Returns:
15 A new string with the original string repeated
16 """
17 # Create a list with the specified length, fill it with the current string,
18 # and join all elements into a single string
19 return ''.join([self] * times)
20
21
22# Alternative approach: Monkey-patching the built-in str class
23# Note: This is generally not recommended in Python but matches the original intent
24def replicate(self, times: int) -> str:
25 """
26 Replicates the string a specified number of times
27
28 Args:
29 times: The number of times to replicate the string
30
31 Returns:
32 A new string with the original string repeated
33 """
34 # Multiply the string by the specified number of times
35 # Python's string multiplication is more idiomatic than array/list joining
36 return self * times
37
38
39# Attach the method to the str class
40# This modifies the built-in str type globally
41str.replicate = replicate
42
1/**
2 * StringReplicator class provides utility methods for string replication
3 * Since Java doesn't support prototype extension like TypeScript/JavaScript,
4 * we use a utility class with static methods
5 */
6public class StringReplicator {
7
8 /**
9 * Replicates the string a specified number of times
10 * @param str - The string to be replicated
11 * @param times - The number of times to replicate the string
12 * @return A new string with the original string repeated
13 */
14 public static String replicate(String str, int times) {
15 // Validate input parameters
16 if (str == null) {
17 return null;
18 }
19
20 if (times <= 0) {
21 return "";
22 }
23
24 // Create a StringBuilder for efficient string concatenation
25 StringBuilder result = new StringBuilder(str.length() * times);
26
27 // Append the string the specified number of times
28 for (int i = 0; i < times; i++) {
29 result.append(str);
30 }
31
32 // Return the concatenated string
33 return result.toString();
34 }
35
36 /**
37 * Alternative implementation using Java 11+ String.repeat() method
38 * @param str - The string to be replicated
39 * @param times - The number of times to replicate the string
40 * @return A new string with the original string repeated
41 */
42 public static String replicateUsingRepeat(String str, int times) {
43 // Validate input parameters
44 if (str == null) {
45 return null;
46 }
47
48 if (times <= 0) {
49 return "";
50 }
51
52 // Use built-in repeat method (available in Java 11+)
53 return str.repeat(times);
54 }
55}
56
1#include <string>
2#include <sstream>
3
4// Extension class to add replicate functionality to strings
5class StringExtensions {
6public:
7 /**
8 * Replicates a string a specified number of times
9 * @param str - The string to replicate
10 * @param times - The number of times to replicate the string
11 * @return A new string with the original string repeated
12 */
13 static std::string replicate(const std::string& str, int times) {
14 // Handle edge cases
15 if (times <= 0) {
16 return "";
17 }
18
19 // Create a string stream for efficient string concatenation
20 std::stringstream result;
21
22 // Append the string 'times' number of times
23 for (int i = 0; i < times; ++i) {
24 result << str;
25 }
26
27 // Return the concatenated string
28 return result.str();
29 }
30};
31
32// Alternative implementation using string reserve for better performance
33class StringUtils {
34public:
35 /**
36 * Replicates a string a specified number of times (optimized version)
37 * @param str - The string to replicate
38 * @param times - The number of times to replicate the string
39 * @return A new string with the original string repeated
40 */
41 static std::string replicate(const std::string& str, int times) {
42 // Handle edge cases
43 if (times <= 0) {
44 return "";
45 }
46
47 // Pre-allocate memory for better performance
48 std::string result;
49 result.reserve(str.length() * times);
50
51 // Append the string 'times' number of times
52 for (int i = 0; i < times; ++i) {
53 result += str;
54 }
55
56 return result;
57 }
58};
59
1// Extend the global String interface to include the replicate method
2declare global {
3 interface String {
4 /**
5 * Replicates the string a specified number of times
6 * @param times - The number of times to replicate the string
7 * @returns A new string with the original string repeated
8 */
9 replicate(times: number): string;
10 }
11}
12
13// Implementation of the replicate method for String prototype
14String.prototype.replicate = function (times: number): string {
15 // Create an array with the specified length, fill it with the current string,
16 // and join all elements into a single string
17 return new Array(times).fill(this.valueOf()).join('');
18};
19
20// Export empty object to make this file a module
21export {};
22
Time and Space Complexity
Time Complexity: O(n)
where n
is the value of the times
parameter.
The time complexity breaks down as follows:
new Array(times)
creates an array of sizetimes
-O(n)
.fill(this)
iterates through the array to fill each element with the string reference -O(n)
.join('')
iterates through the array to concatenate all elements into a single string -O(n)
Since these operations are sequential, the overall time complexity is O(n) + O(n) + O(n) = O(n)
.
Space Complexity: O(n * m)
where n
is the value of the times
parameter and m
is the length of the original string.
The space complexity analysis:
new Array(times)
creates an array withtimes
elements -O(n)
space.fill(this)
populates the array with references to the string (not copies), so no additional space beyond the references.join('')
creates a new string of lengthtimes * m
wherem
is the length of the original string -O(n * m)
space- The intermediate array also holds
n
references -O(n)
space
The dominant factor is the final string of size O(n * m)
, making the overall space complexity O(n * m)
.
Common Pitfalls
1. Not Handling Negative or Non-Integer Input
The implementation doesn't validate the times
parameter. Passing negative numbers or non-integers can cause unexpected behavior:
- In TypeScript:
new Array(-1)
throws a RangeError - In Python: Negative multiplication returns an empty string, which might not be the intended behavior
Solution:
String.prototype.replicate = function (times: number) {
// Validate input
if (times < 0 || !Number.isInteger(times)) {
throw new Error('Parameter must be a non-negative integer');
}
return new Array(times).fill(this).join('');
};
def replicate(self, times: int) -> str:
if not isinstance(times, int) or times < 0:
raise ValueError('Parameter must be a non-negative integer')
return self * times
2. Memory Overflow with Large Numbers
Creating very large arrays or strings can cause memory issues. For example, "hello".replicate(1000000000)
would attempt to create an enormous string.
Solution: Add a reasonable upper limit:
String.prototype.replicate = function (times: number) {
const MAX_REPLICATIONS = 1000000; // Set reasonable limit
if (times > MAX_REPLICATIONS) {
throw new Error(`Cannot replicate more than ${MAX_REPLICATIONS} times`);
}
return new Array(times).fill(this).join('');
};
3. Type Safety Issues in TypeScript
Without proper type declaration, TypeScript will throw compilation errors when trying to use the replicate
method. Forgetting the declare global
block is a common mistake.
Solution: Always include the type declaration before implementation:
declare global {
interface String {
replicate(times: number): string;
}
}
export {}; // Make this file a module
4. Mutating Built-in Prototypes (Python)
Monkey-patching built-in types like str
in Python can lead to:
- Conflicts with third-party libraries
- Unexpected behavior in other parts of the codebase
- Difficulty in debugging
Solution: Use a wrapper class or utility function instead:
def replicate_string(s: str, times: int) -> str:
"""Standalone function that doesn't modify built-in types"""
if not isinstance(times, int) or times < 0:
raise ValueError('Times must be a non-negative integer')
return s * times
# Or use a wrapper class
class ReplicableString(str):
def replicate(self, times: int) -> str:
return self * times
5. Performance Issues with Array Join Approach
In TypeScript, creating an array and then joining it has overhead compared to simple string concatenation for small repetitions.
Solution: Use a more efficient approach for small values:
String.prototype.replicate = function (times: number) {
if (times <= 0) return '';
if (times === 1) return this.toString();
// For small numbers, use simple concatenation
if (times < 10) {
let result = '';
for (let i = 0; i < times; i++) {
result += this;
}
return result;
}
// For larger numbers, use array join
return new Array(times).fill(this).join('');
};
Depth first search is equivalent to which of the tree traversal order?
Recommended Readings
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!