281. Zigzag Iterator

Description

Given two 1d vectors, implement an iterator to return their elements alternately.

Example:

Input:
v1 = [1,2]
v2 = [3,4,5,6]

Output: `[1,3,2,4,5,6]

Explanation:By calling next repeatedly until hasNext returns false,
the order of elements returned by next should be: [1,3,2,4,5,6].
Follow up: What if you are given k 1d vectors? How well can your code be extended to such cases?

Clarification ****for the follow up question****:
The "Zigzag" order is not clearly defined and is ambiguous for k > 2 cases. If "Zigzag" does not look right to you, replace "Zigzag" with "Cyclic". For example:

Input:
[1,2,3]
[4,5,6,7]
[8,9]

Output: [1,4,8,2,5,9,3,6,7].

Iterator, O(n), S(1)

public class ZigzagIterator {
    private Iterator[] iters;
    private int index;
    private Integer next;
    
    public ZigzagIterator(List v1, List v2) {
        iters = new Iterator[] {v1.iterator(), v2.iterator()};
        readNext();
    }
    
    private void readNext() {
        if (next != null) {
            return;
        }
        
        if (iters[index % 2].hasNext()) {
            next = iters[index % 2].next();
            ++index;
        } else {
            if (iters[(index + 1) % 2].hasNext()) {
                next = iters[(index + 1) % 2].next();
                ++index;
            }
        }
    }

    public int next() {
        if (!hasNext()) {
            return Integer.MIN_VALUE;
        }
        int tmp = next;
        next = null;
        return tmp;
    }

    public boolean hasNext() {
        readNext();
        return next != null;
    }
}

/**
 * Your ZigzagIterator object will be instantiated and called as such:
 * ZigzagIterator i = new ZigzagIterator(v1, v2);
 * while (i.hasNext()) v[f()] = i.next();
 */

Follow-up: K iterators, O(n), S(k)

像上面这么写是不是太麻烦了?其实没有必要提前读取next val,因为list iterator自己就帮我们封装好了hasNext和next。我们可以在hasNext()时将iterator pos移动到下一个可以读取的iterator上,然后在next中直接返回其next() val,并移动pos即可。看下面这个解法:

public class ZigzagIterator {
    private Iterator[] iters;
    private int pos;
    private int k;
    
    public ZigzagIterator(List v1, List v2) {
        iters = new Iterator[] {v1.iterator(), v2.iterator()};
        k = iters.length;
    }

    public int next() {
        if (!hasNext()) {
            return Integer.MIN_VALUE;
        }
        int next = iters[pos].next();   // read from iterator that pos is at
        pos = (pos + 1) % k;            // move pos forward
        return next;
    }

    public boolean hasNext() {
        // if current iterator has next, return directly
        if (iters[pos].hasNext()) {
            return true;
        }
        // iterator through the circular arr to find a valid iterator
        for (int i = (pos + 1) % k; i != pos; i = (i + 1) % k) {
            if (iters[i].hasNext()) {
                pos = i;    // move pos to this iterator
                return true;
            }
        }
        
        return false;
    }
}

/**
 * Your ZigzagIterator object will be instantiated and called as such:
 * ZigzagIterator i = new ZigzagIterator(v1, v2);
 * while (i.hasNext()) v[f()] = i.next();
 */

更牛掰的还可以这样,用LinkedList保存若干个可用的iterators。每次读取next时,将头部的iterator取出,读取,如果该iter已经没有剩余了则抛弃掉,否则将它append到list的尾部。这样就能保证循环读取k个iterators!好妙啊!

public class ZigzagIterator {
    private List> list;
    
    public ZigzagIterator(List v1, List v2) {
        list = new LinkedList<>();  // tricky
        if (!v1.isEmpty()) {
            list.add(v1.iterator());
        }
        if (!v2.isEmpty()) {
            list.add(v2.iterator());
        }
    }

    public int next() {
        Iterator head = list.remove(0); // remove head iterator
        int next = head.next();
        if (head.hasNext()) {
            list.add(head);     // append it to the tail
        }
        
        return next;
    }

    public boolean hasNext() {
        return !list.isEmpty();
    }
}

/**
 * Your ZigzagIterator object will be instantiated and called as such:
 * ZigzagIterator i = new ZigzagIterator(v1, v2);
 * while (i.hasNext()) v[f()] = i.next();
 */

你可能感兴趣的:(281. Zigzag Iterator)