zoukankan      html  css  js  c++  java
  • 158. Read N Characters Given Read4 II

    题目:

    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.

    链接:  http://leetcode.com/problems/read-n-characters-given-read4-ii-call-multiple-times/

    题解:

    又是比较难理解题意的一题...call multiple times,举个例子呀, 没例子咋理解。尝试了好几次才弄明白意思。给定read4,跟上一题一样,求可以call multiple times的read()。假如文件字符串是"abc",我们调用read(1),应该返回"a",再调用read(2),应该返回bc"。这里要注意的是,之前我们再第一次调用的时候,read4就已经读取了"abc",所以这道题其实就是要在上一题的基础上处理这种情况。解决方法不难,我们可以用一个queue来存储多读取的部分,然后在下次调用read的时候,根据情况判断,先读queue里面上次读剩下的数据,再进行下面的读取。也可以把read4的buffer放在global,然后用一个int型的offset来记录上次读了read4的多少。由于这个global buffer不会超过4,所以space complexity算是O(1)的。 LeetCode有些题真的很难读懂题意。

    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
         */
         
        private Queue<Character> q;
        private boolean EOF;
        
        public Solution() {
            this.q = new LinkedList<>();
            this.EOF = false;
        }
        
        public int read(char[] buf, int n) {
            char[] read4Buffer = new char[4];
            int bytesRead = 0;
            
            while (!q.isEmpty() && bytesRead < n)             //try read queue buffer first
                buf[bytesRead++] = q.poll();
            
            while(!this.EOF && bytesRead < n) {
                int read4Bytes = read4(read4Buffer);
                if(read4Bytes < 4)
                    this.EOF = true;
                int bytes = Math.min(n - bytesRead, read4Bytes);
                System.arraycopy(read4Buffer, 0, buf, bytesRead, bytes);
                bytesRead += bytes;
                
                if(bytes < 4) {                                 //push read4 reminder to q for next read
                    for(int i = bytes; i < read4Bytes; i++)
                        this.q.offer(read4Buffer[i]);
                }
            }
            
            return bytesRead;
        }
    }

    二刷:

    这回题意理解得还算比较顺利。就是给一个read4()的api,每次最多读取4个char,要求实现read,读取n个char。这里n可以小于read4()返回的数字,也可以大于。

    问题的关键是要储存多读的字符,我们使用一个queue就可以简单解决。每次调用read()的时候,先检查queue是否为空,假如不为空则先从queue中读取。接下来,假如仍然没有读到n个字符,我们就跟上一题一样,调用read4()来不断读取。 要注意多读的字符,我们要保存到queue中。最后返回一共读取的字符数就可以了。

    也可以理解为把缓存中的东西持久化。

    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
         */
        Queue<Character> remainingChars = new LinkedList<>(); 
         
        public int read(char[] buf, int n) {
            char[] read4Buf = new char[4];
            int read4Count = 0;
            int totalCharsRead = 0;
            while (remainingChars.size() > 0 && totalCharsRead < n) {
                buf[totalCharsRead++] = remainingChars.poll();
            }
            //if (totalCharsRead == n) return n;
            while ((read4Count = read4(read4Buf)) > 0) {
                int i = 0;
                while (i < read4Count && totalCharsRead < n) {
                    buf[totalCharsRead++] = read4Buf[i++];
                }
                while (i < read4Count) {
                    remainingChars.offer(read4Buf[i++]);
                }
            }
            return totalCharsRead;
        }
    }

    Reference:

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

    https://leetcode.com/discuss/21219/a-simple-java-code

    https://leetcode.com/discuss/21393/finally-get-question-understood-and-ac-by-c

    https://leetcode.com/discuss/25200/my-python-40ms-solution

    http://www.cnblogs.com/EdwardLiu/p/4240616.html

  • 相关阅读:
    HDU 1002 A + B Problem II
    HDU 2602 Bone Collector WA谁来帮忙找找错
    爬楼梯问题-最大迈两步
    2106 Problem F Shuffling Along 中石油-未提交-->已提交
    2101 Problem A Snake Filled
    2078 Problem H Secret Message 中石油-未提交-->已提交
    有关 时间 空间 以及 数据类型 的总结
    hdu 2510
    hdu 1133 卡特兰 高精度
    hdu 2067
  • 原文地址:https://www.cnblogs.com/yrbbest/p/4489712.html
Copyright © 2011-2022 走看看