@Override public Trie optimize(Trie orig){
  List<CharSequence> cmds=orig.cmds;
  List<Row> rows=new ArrayList<>();
  List<Row> orows=orig.rows;
  int remap[]=new int[orows.size()];
  for (int j=orows.size() - 1; j >= 0; j--) {
    Row now=new Remap(orows.get(j),remap);
    boolean merged=false;
    for (int i=0; i < rows.size(); i++) {
      Row q=merge(now,rows.get(i));
      if (q != null) {
        rows.set(i,q);
        merged=true;
        remap[j]=i;
        break;
      }
    }
    if (merged == false) {
      remap[j]=rows.size();
      rows.add(now);
    }
  }
  int root=remap[orig.root];
  Arrays.fill(remap,-1);
  rows=removeGaps(root,rows,new ArrayList<Row>(),remap);
  return new Trie(orig.forward,remap[root],cmds,rows);
}

@ Override public Trie optimize ( Trie orig ) { List < CharSequence > cmds = orig . cmds ; List < Row > rows = new ArrayList < > ( ) ; List < Row > orows = orig . rows ; int remap [ ] = new int [ orows . size ( ) ] ; for ( int j = orows . size ( ) - 1 ; j >= 0 ; j -- ) { Row now = new Remap ( orows . get ( j ) , remap ) ; boolean merged = false ; for ( int i = 0 ; i < rows . size ( ) ; i ++ ) { Row q = merge ( now , rows . get ( i ) ) ; if ( q != null ) { rows . set ( i , q ) ; merged = true ; remap [ j ] = i ; break ; } } if ( merged == false ) { remap [ j ] = rows . size ( ) ; rows . add ( now ) ; } } int root = remap [ orig . root ] ; Arrays . fill ( remap , - 1 ) ; rows = removeGaps ( root , rows , new ArrayList < Row > ( ) , remap ) ; return new Trie ( orig . forward , remap [ root ] , cmds , rows ) ; }
optimize ( remove empty rows ) from the given trie and return the resulting trie .
