Problem
Using a read7() method that returns 7 characters from a file, implement readN(n) which reads n characters.
For example, given a file with the content “Hello world”, three read7() returns “Hello w”, “orld” and then “”.
Solution
Method 1 - Using Iteration
Here are the steps:
- Buffer Management: Maintain a buffer to store characters read by
read7()
that weren’t consumed byreadN(n)
calls. - Reading
n
Characters: Continuously read usingread7()
until we have at leastn
characters in total. Ifread7()
returns fewer than 7 characters, we’ve likely reached the end of the file. - Serve the Required Characters: Serve characters from the buffer to fulfill the
readN(n)
request.
Code
Java
public class FileReader {
private String content;
private int index;
public FileReader(String content) {
this.content = content;
this.index = 0;
}
public String read7() {
if (index >= content.length()) {
return "";
}
int end = Math.min(index + 7, content.length());
String result = content.substring(index, end);
index += 7;
return result;
}
}
public class Solution {
private FileReader fileReader;
private Queue<Character> buffer;
public Solution(FileReader fileReader) {
this.fileReader = fileReader;
this.buffer = new LinkedList<>();
}
public String readN(int n) {
StringBuilder result = new StringBuilder();
while (result.length() < n) {
// If buffer is empty, read more characters using read7()
if (buffer.isEmpty()) {
String readData = fileReader.read7();
if (readData.isEmpty()) {
break;
}
for (char c : readData.toCharArray()) {
buffer.offer(c);
}
}
// Add buffered characters to the result
while (!buffer.isEmpty() && result.length() < n) {
result.append(buffer.poll());
}
}
return result.toString();
}
}
Python
class FileReader:
def __init__(self, content):
self.content = content
self.index = 0
def read7(self):
if self.index >= len(self.content):
return ""
result = self.content[self.index : self.index + 7]
self.index += 7
return result
class Solution:
def __init__(self, file_reader):
self.file_reader = file_reader
self.buffer = []
def readN(self, n):
result = []
while len(result) < n:
if not self.buffer:
self.buffer = list(self.file_reader.read7())
if not self.buffer:
break
remaining_len = n - len(result)
result += self.buffer[:remaining_len]
self.buffer = self.buffer[remaining_len:]
return "".join(result)
Complexity
- ⏰ Time complexity:
O(n)
- Creating and initializing theFileReader
andSolution
objects themselves are ( O(1) ) operations and do not depend on input size ( n ). - The main work is done in thereadN(int n)
method.- Every time
read7()
is called, it processes up to 7 characters. Therefore, in the worst-case scenario,read7()
will be called ( O(\frac{n+6}{7}) = O(\frac{n}{7}) ) times to readn
characters. - Each character read by
read7()
is processed in constant time ( O(1) ).
- Every time
- 🧺 Space complexity:
O(n)
- The buffer is used to store up to 6 unused characters from
read7()
. Hence, the buffer space is at most 6 characters. - The result string that stores characters read from the buffer and
read7()
can hold up ton
characters. - Other variables such as the
StringBuilder
and counters (likeresult
,remaining_len
) use constant space.
- The buffer is used to store up to 6 unused characters from