Leetcode 251. Flatten 2D Vector

鏈接在此:Flatten 2D Vector - LeetCode

直接的思路

比較直接的思路就是用兩個(gè)pointer,p指v里面的子array,q指子array里面,讀數(shù)就從v[p][q]讀,然后增加q的值,假如q已經(jīng)到頭了,就再增加p并重置p。
值得注意的一點(diǎn)是要處理v里面的空array的情況。可以在hasNext()里面把空array都過(guò)濾掉,這樣就不會(huì)影響。代碼:

class Vector2D {
        private int p, q;
        private final int[][] v;

        public Vector2D(int[][] v) {
            this.v = v;
            p = 0;
            q = 0;
        }

        public int next() {
            hasNext();
            int val = v[p][q];
            q++;
            if (q == v[p].length) {
                p++;
                q = 0;
            }
            return val;
        }

        public boolean hasNext() {
            while (p < v.length && v[p].length == 0) p++;
            return p < v.length;
        }
}

此代碼擊敗了99.4%,說(shuō)明效率還是不錯(cuò)的。

Iterator做法

題目的follow up要求使用Iterator,所以還是嘗試一下。
Iterator接口主要有三個(gè)函數(shù):

image.png

此處不需要remove(),前兩個(gè)就夠了。難點(diǎn)在于怎么操作這種2D array的Iterator。Array在Java 8之前是不支持Iterator的(除了一些第三方庫(kù)),因此至少需要把它轉(zhuǎn)化成List才能用。不過(guò)Java 8帶來(lái)了stream,可以另辟蹊徑地通過(guò)Arrays.stream(arr).iterator()達(dá)到目的。
有了Iterator之后,本質(zhì)上還是和雙指針類似,外圍rowIter負(fù)責(zé)遍歷v,內(nèi)圍colIter負(fù)責(zé)遍歷v[i]。當(dāng)然還是有細(xì)節(jié)不同的,最大的不同是rowIter調(diào)用next()時(shí)必須馬上賦給colIter,不然就沒(méi)了。代碼如下:

class Vector2D {
        private final Iterator<int[]> rowIter;
        private Iterator<Integer> colIter;

        public Vector2D(int[][] v) {
            rowIter = Arrays.stream(v).iterator();
            if (rowIter.hasNext()) colIter = Arrays.stream(rowIter.next()).iterator();
        }

        public int next() {
            hasNext();
            return colIter.next();
        }

        public boolean hasNext() {
            if (colIter == null) return false;
            while (!colIter.hasNext() && rowIter.hasNext()) colIter = Arrays.stream(rowIter.next()).iterator();
            return colIter.hasNext();
        }
}

stream是Lazy的,意味著Arrays.stream(v).iterator()事先并不會(huì)遍歷整個(gè)v,所以時(shí)間復(fù)雜度并未增加。
假如函數(shù)傳入的是List,可能做法更原汁原味一些:

class List2D {
        private final Iterator<List<Integer>> rowIter;
        private Iterator<Integer> colIter;

        public List2D(List<List<Integer>> v) {
            rowIter = v.iterator();
            if (rowIter.hasNext()) colIter = rowIter.next().iterator();
        }

        public int next() {
            hasNext();
            int val = colIter.next();
            if (!colIter.hasNext() && rowIter.hasNext()) {
                colIter = rowIter.next().iterator();
            }
            return val;
        }

        public boolean hasNext() {
            if (colIter == null) return false;
            while (!colIter.hasNext() && rowIter.hasNext()) colIter = rowIter.next().iterator();
            return colIter.hasNext();
        }
    }

套娃一下,通過(guò)Leetcode的測(cè)試,證明上面的代碼同樣是對(duì)的:

import java.util.*;
import java.util.stream.Collectors;

public class Vector2D {

    private static class List2D {
        private final Iterator<List<Integer>> rowIter;
        private Iterator<Integer> colIter;

        public List2D(List<List<Integer>> v) {
            rowIter = v.iterator();
            if (rowIter.hasNext()) colIter = rowIter.next().iterator();
        }

        public int next() {
            hasNext();
            int val = colIter.next();
            if (!colIter.hasNext() && rowIter.hasNext()) {
                colIter = rowIter.next().iterator();
            }
            return val;
        }

        public boolean hasNext() {
            if (colIter == null) return false;
            while (!colIter.hasNext() && rowIter.hasNext()) colIter = rowIter.next().iterator();
            return colIter.hasNext();
        }
    }

    private final List2D list2D;

    public Vector2D(int[][] v) {
        List<List<Integer>> lists = Arrays.stream(v)
                .map(internalArray -> Arrays.stream(internalArray).boxed().collect(Collectors.toList()))
                .collect(Collectors.toList());
        list2D = new List2D(lists);
    }

    public int next() {
        return list2D.next();
    }

    public boolean hasNext() {
        return list2D.hasNext();
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容