Skip to content

Commit 410707a

Browse files
Added solution for the read input buffer problem.
1 parent 5530dcb commit 410707a

File tree

3 files changed

+120
-0
lines changed

3 files changed

+120
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ Happy to accept any contributions to this in any langugage.
5454

5555
## Hard
5656
1. [Find Missing Positive](https://leetcode.com/problems/first-missing-positive/) | [Solution](./level_hard/LeetCode_41_Hard.ts)
57+
2. [Read N Characters Given Read 4 II - Call Multiple Times - LeetCode 158](https://leetcode.com/problems/read-n-characters-given-read4-ii-call-multiple-times/) | [Solution 1](./level_hard/LeetCode_158_Hard.java) | [Solution 2 Optimized](./level_hard/LeetCode_158_Hard_1.java)
5758

5859
## Sorting
5960
1. Bubble Sort | [Solution](./sorting/Sort_Bubble.js)

level_hard/LeetCode_158_Hard.java

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/**
2+
* The read4 API is defined in the parent class Reader4.
3+
* int read4(char[] buf4);
4+
*/
5+
/**
6+
* Problem: Leetcode 158
7+
*/
8+
public class Solution extends Reader4 {
9+
10+
char[] buffer = new char[16];
11+
int writePtr = 0;
12+
int readPtr = 0;
13+
14+
/**
15+
* @param buf Destination buffer
16+
* @param n Number of characters to read
17+
* @return The number of actual characters read
18+
*/
19+
public int read(char[] buf, int n) {
20+
if (writePtr - readPtr >= n) {
21+
// All data is already available in the buffer, read and return
22+
this.copyRange(buffer, readPtr, n + readPtr, buf, 0);
23+
this.readPtr += n;
24+
return n;
25+
} else {
26+
// Not enough items are available, try to get more items into the internal buffer.
27+
this.readInternal(n - (writePtr - readPtr));
28+
if (writePtr - readPtr >= n) {
29+
// All the n items can be fetched and updated.
30+
this.copyRange(buffer, readPtr, n + readPtr, buf, 0);
31+
this.readPtr += n;
32+
return n;
33+
} else {
34+
this.copyRange(buffer, readPtr, writePtr, buf, 0);
35+
int itemsRead = writePtr - readPtr;
36+
this.readPtr = writePtr;
37+
return itemsRead;
38+
}
39+
}
40+
}
41+
42+
private void readInternal(int n) {
43+
int readItems = n % 4 == 0 ? n : (n/4 + 1) * 4;
44+
45+
if (this.buffer.length < this.writePtr + readItems) {
46+
this.expandInternalBuffer(this.writePtr + readItems);
47+
}
48+
49+
while(readItems > 0) {
50+
char[] buff4 = new char[4];
51+
int newItems = this.read4(buff4);
52+
if (newItems == 0) break;
53+
this.copyRange(buff4, 0, newItems, this.buffer, this.writePtr);
54+
this.writePtr += newItems;
55+
readItems -= newItems;
56+
}
57+
}
58+
59+
private void expandInternalBuffer(int length) {
60+
int newLength = (length / 16 + 1) * 16;
61+
char[] newBuffer = new char[newLength];
62+
this.copyRange(buffer, 0, this.writePtr, newBuffer, 0);
63+
this.buffer = newBuffer;
64+
}
65+
66+
// Copy the items from the input buffer to the output buffer.
67+
private void copyRange(char[] source,
68+
int sourceBeg,
69+
int sourceEnd,
70+
char[] target,
71+
int targetBeg) {
72+
// for (int idx = sourceBeg; idx < sourceEnd; idx++) {
73+
// target[targetBeg++] = source[idx];
74+
// }
75+
System.arraycopy(source, sourceBeg, target, targetBeg, sourceEnd - sourceBeg);
76+
}
77+
}

level_hard/LeetCode_158_Hard_1.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* The read4 API is defined in the parent class Reader4.
3+
* int read4(char[] buf4);
4+
*/
5+
public class Solution extends Reader4 {
6+
7+
/**
8+
* Solution uses a buffering approach in order to read and write. The write operation
9+
* continues to write the elements into the output buffer one step at a time in the iteration
10+
* loop. The read step updates the internal read buffer when the internal buffer gets empty.
11+
*/
12+
13+
private char[] intBuf = new char[4];
14+
private int intBufWritePtr = 0;
15+
private int intBufReadPtr = 0;
16+
17+
/**
18+
* @param buf Destination buffer
19+
* @param n Number of characters to read
20+
* @return The number of actual characters read
21+
*/
22+
public int read(char[] buf, int n) {
23+
24+
int writeLoc = 0;
25+
26+
// Repeat adding new elements till the write location does not reach till n-1
27+
while (n > writeLoc) {
28+
if (intBufReadPtr < intBufWritePtr) {
29+
// If there is something already existing in the input buffers, use it.
30+
buf[writeLoc++] = intBuf[intBufReadPtr++];
31+
} else {
32+
// If not, lets fetch more items and fill the internal buffer for further use.
33+
int totalItems = this.read4(intBuf);
34+
intBufReadPtr = 0;
35+
intBufWritePtr = totalItems;
36+
if (totalItems == 0) break;
37+
}
38+
}
39+
40+
return writeLoc;
41+
}
42+
}

0 commit comments

Comments
 (0)