157. Read N Characters Given Read4

题目:

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 will only be called once for each test case.

链接: http://leetcode.com/problems/read-n-characters-given-read4/

题解:

英文不好,很难理解题意。简单讲就是已经有个API - read4(char[] buf),每次从文件里读取最多4个bytes到char[] buf里。要求根据read4来实现read(char[] buf, n),就是可以从文件中读取n个字符。这里我们要注意的就是,假如read4读取的字符数小于4,那么即到了文件尾部,我们可以使用一个变量EOF来记录这个时刻。除此之外就是一些判断和拷贝了。这里用到了System.arraycopy()。

Time Complexity - O(n),Space Complexity - O(1)

/* The read4 API is defined in the parent class Reader4.
      int read4(char[] buf); */

public class Solution extends Reader4 {
    /**
     * @param buf Destination buffer
     * @param n   Maximum number of characters to read
     * @return    The number of characters read
     */
    public int read(char[] buf, int n) {
        char[] read4Buffer = new char[4];
        boolean EOF = false;
        int bytesRead = 0;
        
        while(!EOF && bytesRead < n) {
            int read4Bytes = read4(read4Buffer);
            if(read4Bytes < 4)
                EOF = true;
            int bytes = Math.min(n - bytesRead, read4Bytes);
            System.arraycopy(read4Buffer, 0, buf, bytesRead, bytes);
            bytesRead += bytes;
        }
        
        return bytesRead;
    }
}

 

二刷:

  1. 先建立一个read4Buf来保存使用read4 api之后读取的数据。 并且我们建立一个boolean EOF来代表是否读到了文件末尾,即read4返回的值小于4。
  2. 接下来我们用一个while循环来读取
  3. 当read4返回的值小于4的时候,我们设置EOF = true,即在下一次循环跳出
  4. 接下来我们来判断每次究竟要读取多少个bytes, 这个bytesToRead = Math.min(n - bytesRead,read4Bytes), 就是还剩多少字符要读取,以及read4 api的返回值里较小的一个
  5. 我们根据这个bytesToRead将read4Buf里的值拷贝到buf里,并且增加bytesRead
  6. 最后循环结束后,我们返回bytesRead就是我们究竟读取了多少字符。

Java:

Time Complexity - O(n),Space Complexity - O(1)

/* The read4 API is defined in the parent class Reader4.
      int read4(char[] buf); */

public class Solution extends Reader4 {
    /**
     * @param buf Destination buffer
     * @param n   Maximum number of characters to read
     * @return    The number of characters read
     */
    public int read(char[] buf, int n) {
        char[] read4Buf = new char[4];
        int bytesRead = 0;
        boolean EOF = false;
        while (!EOF && bytesRead <= n) {
            int read4Bytes = read4(read4Buf);
            if (read4Bytes < 4) {
                EOF = true;
            }
            int bytesToRead = Math.min(n - bytesRead, read4Bytes);
            for (int i = 0; i < bytesToRead; i++) {
                buf[bytesRead++] = read4Buf[i];    
            }
        }
        return bytesRead;
    }
}

 

三刷:

前面写得比较麻烦,这次换了新写法。我们首先创建一个read4Buf用来保存每次调用read4 api所返回的字符。建立两个变量,一个read4Count用来记录read4调用实际返回了多少个字符,另外一个totalCharRead表示我们总共已经读取了多少字符。使用一个while循环,在(read4Count = read4(read4Buf)) > 0的时候,每次拷贝这回read4调用读取的字符到输出buf中。注意拷贝时的条件是i < read4Count && totalCharRead < n

Java:

/* The read4 API is defined in the parent class Reader4.
      int read4(char[] buf); */

public class Solution extends Reader4 {
    /**
     * @param buf Destination buffer
     * @param n   Maximum number of characters to read
     * @return    The number of characters read
     */
    public int read(char[] buf, int n) {
        char[] read4Buf = new char[4];
        int totalCharRead = 0;
        int read4Count = 0;
        while ((read4Count = read4(read4Buf)) > 0) {
            for (int i = 0; i < read4Count && totalCharRead < n; i++) {
                buf[totalCharRead++] = read4Buf[i];
            }
        }
        return totalCharRead;
    }
}

 

Reference:

https://leetcode.com/discuss/19573/accepted-clean-java-solution

posted @ 2015-05-09 12:35  YRB  阅读(895)  评论(1编辑  收藏  举报