Iterator 2

Iterator 2


Flatten 2d vector 
21.13

51.52


Flatten nested list 
54.36


1.15 peek iterator




Merge list of list , using peek iterator 
1.27



Bst 
1.49

=======================


// flatten 2d vector

input; 

[
  [1,2]
  [3]
  [4,5,6]
  
]


output: 
[1,2,3,4,5,6]
//

public class Vector2D implements Iterator<Integer> {
  List<List<Integer>> vec;
  Integer indexVec;
  Integer indexEle;
  
  public Vector2D(List<List<Integer>> vec2d){
    vec = vec2d;    //////// vec 
    indexVec = 0;
    indexEle = 0;
    
  }
  

  @Override
  public Integer next(){
    if(hasNext()){
      return vec.get(indexVec).get(indexEle++);    ///////// vec
    }else{
      return null;
    }
  }


  @Override 
  public boolean hasNext(){
    while (indexVec < vec.size()){
      if(indexEle < vec.get(indexVec).size()){
        return true;
      }else{
        indexVec++;
        indexEle = 0;
      }
    }
    return false;
  }
  
}

// Flatten nested list 

/**
 * // This is the interface that allows for creating nested lists.
 * // You should not implement it, or speculate about its implementation
 * public interface NestedInteger {
 *
 *     // @return true if this NestedInteger holds a single integer, rather than a nested list.
 *     public boolean isInteger();
 *
 *     // @return the single integer that this NestedInteger holds, if it holds a single integer
 *     // Return null if this NestedInteger holds a nested list
 *     public Integer getInteger();
 *
 *     // @return the nested list that this NestedInteger holds, if it holds a nested list
 *     // Return null if this NestedInteger holds a single integer
 *     public List<NestedInteger> getList();
 * }
 */


public class NestedIterator implements Iterator<Integer> {
    Stack<NestedInteger> stack = new Stack<>();
    public NestedIterator(List<NestedInteger> nestedList) {
        for(int i = nestedList.size() - 1; i >= 0; i--) {
            stack.push(nestedList.get(i));
        }
    }

    @Override
    public Integer next() {
      if(hasNext()){
        return stack.pop().getInteger();
      }else{
        return null;
      }
    }

    @Override
    public boolean hasNext() {
        while(!stack.isEmpty()) {
            NestedInteger curr = stack.peek();
            if(curr.isInteger()) {
                return true;
            }
            stack.pop();
            for(int i = curr.getList().size() - 1; i >= 0; i--) {
                stack.push(curr.getList().get(i));
            }
        }
        return false;
    }
}

  

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



// peek iterator 
// peek() returns the next() value but not move the pointer 
// peek() should throw exception when no more element exists 
// {1,2,3,4}
// iterator.peek() : 1
// iterator.next() : 1

// iterator.peek() : 2
// iterator.peek() : 2
// iterator.peek() : 2
// iterator.next() : 2



// peek iterator 
////// from leetcode 


// Java Iterator interface reference:
// https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html
class PeekingIterator implements Iterator<Integer>{
  Integer next = null;
  Iterator<Integer> iter;
  
  public PeekingIterator(Iterator<Integer> iterator){
    iter = iterator;
    if(iter.hasNext()){
      next = iter.next();
    }
  }
  
  public Integer peek(){
    return next;
  }
  
  @Override 
  public Integer next(){
    Integer res = next;
    if(iter.hasNext()){
      next = iter.next();
    }else{
      next = null;
    }
    return res;
  }
  
  @Override 
  public boolean hasNext(){
    if(next == null){
      return false;
    }else{
      return true;
    }
  }

}
  

// merge sorted linked lists into one sorted linked list 
// https://leetcode.com/problems/merge-k-sorted-lists/solution/
  
// time : O(nlogk). n is the number of the nodes in total. k is the number of lists
// the size of the pq is k, everytime we pop or offer an element, it takes logk to percolate up or down the pq 
// to keep the order of pq, which in our case, is that smallest is at the top. 
// since we have to do this n times, so nlogk 
  
// space: O(n+k). because n is the size of the new linked list, k is the size of the pq. 
  

  

 
  class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
      if(lists == null || lists.length == 0) return null;
      
      ListNode dummy = new ListNode(0);
      ListNode cur = dummy;
      
      PriorityQueue<ListNode> pq = new PriorityQueue<ListNode>(lists.length, new Comparator<ListNode>(){
        @Override 
        public int compare(ListNode l1, ListNode l2){
          if(l1.val > l2.val){
            return 1;
          }else if(l1.val < l2.val){
            return -1;
          }else{
            return 0;
          }
        }
      });
      
      
      for(ListNode node : lists){
          if(node != null){    //////
              pq.offer(node);
          }
      }
      
      while(!pq.isEmpty()){
        ListNode current = pq.poll();
        cur.next = current;
        cur = cur.next;
        
        if(current.next != null){
          pq.offer(current.next);
        }
      }
      
      return dummy.next;
    }
}
  






// Merge list of list , using peek iterator 

// input: List<Iterator<Integer>> iters = 
[
[1,2,6],
[3],
[4,5]
]

// output: [1,2,3,4,5,6]

// merge list of list, using peeking iterator 
public List<Integer> merge(List<Iterator<Integer>> iters){
  PriorityQueue<PeekIterator<Integer>> pq = new PriorityQueue<>(iters.size(), 
      new Comparator<PeekIterator<Integer>>(){
        @Override 
        public int compare(PeekIterator<Integer> it1, 
                           PeekIterator<Integer> it2){
          if(it1.peek() > iter2.peek()){
            return 1;
          }else if (it1.peek() < iter2.peek()){
            return -1;
          }else{
            return 0;
          }
        }
  });
  
  for(iterator<Integer> iter : iters){
    if(iter != null && iter.hasNext()){
      pq.offer(new PeekIterator<>(iter));
    }
  }
  
  
  
  List<Integer> result = new ArrayList<>();
  while(!pq.isEmpty()){
    PeekIterator<Integer> iter = pq.poll();
    result.add(iter.next());
    if(iter.hasNext()){
      pq.add(iter);
    }
  }
  return result;
}
  
  
// preorder iterator 
 
public class PreOrderIterator{
  Stack<TreeNode> stack = new Stack<>();
  
  public PreOrderIterator(TreeNode root){
    stack.push(root);
  }
  
  public boolean hasNext(){
    return !stack.isEmpty();
  }
  
  public Integer next(){
    if(hasNext()){
      TreeNode cur = stack.pop();
      if(cur.right != null){
        stack.offer(cur.right);
      }
      if(cur.left != null){
        stack.offer(cur.left);
      }
      return cur.val;
    }else{
      throw new NoSuchElementException();
    }
  }
}
  

  
// preorder traversal iteratively 
  
public List<Integer> preorder(TreeNode root){
  List<Integer> result = new ArrayList<>();
  Stack<TreeNode> stack = new Stack<>();
  stack.push(root);
  while(!stack.isEmpty()){
    TreeNode cur = stack.pop();
    result.add(cur.val);
    if(cur.right != null){
      stack.offer(cur.right);
    }
    if(cur.left != null){
      stack.offer(cur.left);
    }
  }
  return result;
}

  
  
  
  
   
  

// Bst  in order iterator 

public class BSTiterator{

  private Stack<TreeNode> stack = new Stack<>();
  
  public BSTiterator(TreeNode root){
    pushLeft(root);
  
  }
  
  public boolean hasNext(){  // o(1)
    return !stack.isEmpty();
  }
  
  public int next(){  // worse o(n), average o(height)
    if(hasNext()){
      TreeNode cur = stack.pop();
      pushLeft(cur.right);
      return cur.val;
    }else{
      throw new NoSuchElementException;
    }  
  }
  
  private void pushLeft(TreeNode node){
    while(node != null){
      stack.push(node);
      node = node.left;
    }
  }
}



//. follow up : 
1. 173  binary search tree iterator ( in order )  follow up:两个BST,然后按顺序iterate。这个follow up建议大家一定不要想当然,要自己动手写一下,考虑齐全corn case,然后跑出来看看,里面有坑。。写173的人都应该已经有现成的iterator了吧 然后便利两个bst 就是用的两个这样的iterator 每次call next 比较大小 加上我原文中提到的trick就没问题了。。有一个比较巧妙的办法,用Integer 而不是int pointer记录每次iterate到的数字,如果发现Integer cur == null,再call next 赋值。 tongzhang1994

public class TwoBSTiterators(){
  
  BSTiterator iter1;
  BSTiterator iter2;
  Integer next1 = null;
  Integer next2 = null;
  boolean check1;
  boolean check2;
        
  
  public TwoBSTiterators(BSTiterator iter1, BSTiterator iter2){
    
  }
  
  
  
  @Override 
  public boolean hasNext(){
    return iter1.hasNext() || iter2.hasNext();
  }
  
  @Override 
  public Integer next(){
    if(hasNext()){
      if(iter1.hasNext() && iter2.hasNext()){
        
        
        // are we allowed to peek the element on top of each stack ?? 
        // if we are allowed 
        if(stack1.peek() > stack2.peek()){
          return iter2.next();
        }else{
          return iter1.next();
        }
        
        
    //12458
    //379
    //next : 1, 2, 3, 4
     
        
        // if we are not allowed to peek the stacks
        if(check1 != true){
          next1 = iter1.next();  // 1, 2, 4, 5
        }
        
        if(check2 != true){
          next2 = iter2.next();  // 3, 7
        }
        
        if(next1 < next2){
          check2 = true;   // true, 
          check1 = false;  // false
          return next1;    // 1, 2 4
          
        }else{
          check1 = true;  // true
          check2 = false; // false
          return next2;  // 3
        }
        
        
      }else{
        return iter1.hasNext() ? iter1.next() : iter2.next();
    }else{
      throw new NoSuchElementException();
    }
  }
}
  
////

public class TwoBSTiterators(){
  
  BSTiterator iter1;
  BSTiterator iter2;
  Integer next1;
  Integer next2;
  boolean check1;
  boolean check2;
        
  
  public TwoBSTiterators(BSTiterator iter1, BSTiterator iter2){
    BSTiterator iter1 = iter1;
    BSTiterator iter2 = iter2;
    next1 = null;
    next2 = null;
    boolean check1 = false;
    boolean check2 = false;
    
  }
  
  
  
  @Override 
  public boolean hasNext(){
    return iter1.hasNext() || iter2.hasNext();
  }
  
  @Override 
  public Integer next(){
    if(hasNext()){
      if(iter1.hasNext() && iter2.hasNext()){
        
        if(check1 != true){
          next1 = iter1.next();  
        }
        
        if(check2 != true){
          next2 = iter2.next();  
        }
        
        if(next1 < next2){
          check2 = true;   
          check1 = false;  
          return next1;    
          
        }else{
          check1 = true;  
          check2 = false; 
          return next2;  
        }
        
        
      }else{
        return iter1.hasNext() ? iter1.next() : iter2.next();
    }else{
      throw new NoSuchElementException();
    }
  }
}
  

 

posted on 2018-08-09 18:03  猪猪&#128055;  阅读(136)  评论(0)    收藏  举报

导航