Thursday, October 02, 2014

Last Non-repeat Element

Given a stream of object, make a function to return last non repeating object.
(I was confused by definition of steam, it can simply mean a collection of object)

Solution:
use a Set or HashMap to figure out the repeating of objects, then use a Deque to access head or tail in O(1) time. Collection has convenient method to remove object: remove(o).


package LastNonRepeatCharacter;

import java.util.Arrays;
import java.util.Collection;
import java.util.Deque;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import java.util.stream.Stream;
/**
* return last non-repeating object
*
* @author Andrew Ma
*
*/
public class SolutionObject {
 Deque<Object> nonRepeating = new LinkedList<Object>();
 Set<Object> metSoFar = new HashSet<Object>();
 Object getLastNonRepeatCharacter(){
  if(nonRepeating.isEmpty())return null;
  return nonRepeating.getLast();
 }
 public void reset(){
  nonRepeating.clear();
  metSoFar.clear();
 }
 public void stream(Collection<Object> inStream){
  stream(inStream.stream());
 }
 public void stream(Stream<Object> inStream){
  inStream.forEach(e->{
   if(!metSoFar.add(e)){
    nonRepeating.remove(e);//this is from collection, and might be expensive and worst at O(n) depending on implementation
   }
   else
    nonRepeating.addLast(e);
  });

 }

 public static void main(String[] args) {
  SolutionObject s = new SolutionObject();
  String[] str = new String[]{"abc","bcd","cde","def","fee"};
  String[] str2 = {"abc","bcd","cde","def","fee","fee"};
  s.stream(Arrays.asList(str));
  System.out.println("test1:"+s.getLastNonRepeatCharacter());
  s.reset();
  s.stream(Arrays.asList(str2));
  System.out.println("test2:"+s.getLastNonRepeatCharacter());
 }
}

No comments: