341. Flatten Nested List Iterator && 385. Mini Parser

341. Flatten Nested List Iterator

Given a nested list of integers, implement an iterator to flatten it.

Each element is either an integer, or a list -- whose elements may also be integers or other lists.

Example 1:
Given the list [[1,1],2,[1,1]],

By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,1,2,1,1].

Example 2:
Given the list [1,[4,[6]]],

By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,4,6].

 
Solution: Keep unprocessed items in a stack, and expand the first item as necessary and add the entire expanded list to the stack.
 
/**
 * // 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> {

    Deque<NestedInteger> queue;
    
    public NestedIterator(List<NestedInteger> nestedList) {
         queue = new ArrayDeque<NestedInteger>(nestedList);
    }

    @Override
    public Integer next() {
        if(hasNext())
            return queue.remove().getInteger();
        return null;
    }

    @Override
    public boolean hasNext() {
        if(queue.isEmpty())
            return false;
        if(queue.peek().isInteger())
            return true;
        
        while(!queue.peek().isInteger())
        {
            NestedInteger first = queue.remove();
            List<NestedInteger> items = first.getList();
            for(int i = items.size()-1; i>=0; --i){
                queue.push(items.get(i));
            }
            if(queue.isEmpty())
                return false;
        }
        return true;
    }
}

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

 

385. Mini Parser

Given a nested list of integers represented as a string, implement a parser to deserialize it.

Each element is either an integer, or a list -- whose elements may also be integers or other lists.

Note: You may assume that the string is well-formed:

  • String is non-empty.
  • String does not contain white spaces.
  • String contains only digits 0-9[- ,].

Example 1:

Given s = "324",

You should return a NestedInteger object which contains a single integer 324.

Example 2:

Given s = "[123,[456,[789]]]",

Return a NestedInteger object containing a nested list with 2 elements:

1. An integer containing value 123.
2. A nested list containing two elements:
    i.  An integer containing value 456.
    ii. A nested list with one element:
         a. An integer containing value 789.
 
/**
 * // This is the interface that allows for creating nested lists.
 * // You should not implement it, or speculate about its implementation
 * public interface NestedInteger {
 *     // Constructor initializes an empty nested list.
 *     public NestedInteger();
 *
 *     // Constructor initializes a single integer.
 *     public NestedInteger(int value);
 *
 *     // @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();
 *
 *     // Set this NestedInteger to hold a single integer.
 *     public void setInteger(int value);
 *
 *     // Set this NestedInteger to hold a nested list and adds a nested integer to it.
 *     public void add(NestedInteger ni);
 *
 *     // @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 Solution {
    public NestedInteger deserialize(String s) {
        return deserialize(s, new int[]{0});
    }
    
    //Use this function to deserialize a substring starting from index[0] 
    //this substring could either be a pure number(composing of "[\-0-9]")
    //or a list which starts with '[' and ends with ']'.
    //update the index to the next char before exiting.
    public NestedInteger deserialize(String s, int[] index) {
        NestedInteger ret = null;   //either the number or the list
        NestedInteger current = null;  //points to current element if it's a list
        StringBuilder sb = new StringBuilder(); //accumulating all numbers
        
        int i = index[0]; //starting from index[0]
        while(i<s.length()){
            char c = s.charAt(i);
            if((c>='0' && c<='9') || c == '-')
                sb.append(c);
            else if(c == ',' || c == ']') {
                if(current != null) { //it is a list, and current is assigned from [...]
                    ret.add(current);
                    current = null;
                }
                else if(sb.length() > 0) {
                    int number = Integer.valueOf(sb.toString());
                    sb.setLength(0);
                    if(ret == null) //it is a number
                        ret = new NestedInteger(number);
                    else //it is a list, and current element is from integers
                        ret.add(new NestedInteger(number));
                }
            
                if(c == ']') { //this ']' is for closing current substring when it's a list
                    index[0] = i+1; //points to next char
                    return ret;
                }
            }
            else if(c == '[') {
                if(ret == null)
                    ret = new NestedInteger(); //creating a new list
                else { //entering an element of current list
                    int[] next = new int[]{i}; //$next points to a '['
                    current = deserialize(s, next); //now $next points to a char after ']'
                    i = next[0];
                    continue;
                }
            }
            ++i;
        }
        
        index[0] = s.length();
        if(ret == null) {
            int number = Integer.valueOf(sb.toString());
            ret = new NestedInteger(number);
        }
        return ret;
    }
}

 

Solution with stack

/**
 * // This is the interface that allows for creating nested lists.
 * // You should not implement it, or speculate about its implementation
 * public interface NestedInteger {
 *     // Constructor initializes an empty nested list.
 *     public NestedInteger();
 *
 *     // Constructor initializes a single integer.
 *     public NestedInteger(int value);
 *
 *     // @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();
 *
 *     // Set this NestedInteger to hold a single integer.
 *     public void setInteger(int value);
 *
 *     // Set this NestedInteger to hold a nested list and adds a nested integer to it.
 *     public void add(NestedInteger ni);
 *
 *     // @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 Solution {
  public NestedInteger deserialize(String s) {
    if (s.isEmpty())
      return new NestedInteger();
    if (s.charAt(0) != '[')
      return new NestedInteger(Integer.valueOf(s));
    ArrayDeque<NestedInteger> stack = new ArrayDeque<>();
    int tempStart = 0;//tempStart keeps the beginning position of an integer
    for (int j = 0; j < s.length(); ++j) {
      if (s.charAt(j) == '[') {//push a new nested list
        stack.push(new NestedInteger());
        tempStart = j + 1;
      } else if (s.charAt(j) == ']') {//current level nested list has finished
        if (s.charAt(j - 1) >= '0' && s.charAt(j - 1) <= '9') {
          stack.peek().add(new NestedInteger(Integer.valueOf(s.substring(tempStart, j))));
        }
        if (stack.size() > 1) {//current level nested list has an outer nested list
          NestedInteger cur = stack.pop();
          stack.peek().add(cur);
        }
        tempStart = j + 1;
      } else if (s.charAt(j) == ',') {
        if (s.charAt(j - 1) >= '0' && s.charAt(j - 1) <= '9') {
          stack.peek().add(new NestedInteger(Integer.valueOf(s.substring(tempStart, j))));
        }
        tempStart = j + 1;
      }
    }
    return stack.peek();
  }
}

 

 

 
 
posted @ 2016-06-28 03:40  新一代的天皇巨星  阅读(212)  评论(0)    收藏  举报