[LeetCode] 158. Read N Characters Given Read4 II - Call multiple times
The API: int read4(char *buf) reads 4 characters at a time from a file.
The return value is the actual number of characters read. For example, it returns 3 if there is only 3 characters left in the file.
By using the read4 API, implement the function int read(char *buf, int n) that reads n characters from the file.
Note:
The read function may be called multiple times.
157. Read N Characters Given Read4 的拓展,之前只能調用一次,而這裏可以調用多次,又多了一些corner case:
第一次調用時,如果read4讀出的多余字符我們要先將其暫存起來,這樣第二次調用時先讀取這些暫存的字符
第二次調用時,如果連暫存字符都沒讀完,那麽這些暫存字符還得留給第三次調用時使用
所以,難點就在於怎麽處理這個暫存字符。因為用數組和指針控制對第二種情況比較麻煩,且這些字符滿足先進先出,所以我們可以用一個隊列暫存這些字符。這樣,只要隊列不為空,就先讀取隊列。
Java: Time: O(n), Space: O(1)
public class Solution extends Reader4 { Queue<Character> remain = new LinkedList<Character>(); public int read(char[] buf, int n) { int i = 0; // 隊列不為空時,先讀取隊列中的暫存字符 while(i < n && !remain.isEmpty()){ buf[i] = remain.poll(); i++; } for(; i < n; i += 4){ char[] tmp = new char[4]; int len = read4(tmp); // 如果讀到字符多於我們需要的字符,需要暫存這些多余字符 if(len > n - i){ System.arraycopy(tmp, 0, buf, i, n - i); // 把多余的字符存入隊列中 for(int j = n - i; j < len; j++){ remain.offer(tmp[j]); } // 如果讀到的字符少於我們需要的字符,直接拷貝 } else { System.arraycopy(tmp, 0, buf, i, len); } // 同樣的,如果讀不滿4個,說明數據已經讀完,返回總所需長度和目前已經讀到的長度的較小的 if(len < 4) return Math.min(i + len, n); } // 如果到這裏,說明都是完美讀取,直接返回n return n; } }
相關題目:
[LeetCode] 157. Read N Characters Given Read4 用Read4來讀取N個字符
[LeetCode] 158. Read N Characters Given Read4 II - Call multiple times