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 猪猪🐷 阅读(136) 评论(0) 收藏 举报
浙公网安备 33010602011771号