leetcode-341-扁平化嵌套列表迭代器-java

題目及測試

package pid341;
/*  扁平化嵌套列表迭代器

給你一個嵌套的整型列表。請你設計一個迭代器,使其能夠遍歷這個整型列表中的所有整數。

列表中的每一項或者爲一個整數,或者是另一個列表。其中列表的元素也可能是整數或是其他列表。

 

示例 1:

輸入: [[1,1],2,[1,1]]
輸出: [1,1,2,1,1]
解釋: 通過重複調用 next 直到 hasNext 返回 false,next 返回的元素的順序應該是: [1,1,2,1,1]。

示例 2:

輸入: [1,[4,[6]]]
輸出: [1,4,6]
解釋: 通過重複調用 next 直到 hasNext 返回 false,next 返回的元素的順序應該是: [1,4,6]。


*/
public class main {
	
	public static void main(String[] args) {

	}


}
package pid341;

import java.util.Iterator;
import java.util.List;

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();
}

解法1(成功,4ms,較快)

內部有一個stack,index大的先放進去,小的後放進去。next時,彈出最上面的,如果是數字,直接返回。如果不是數字,將列表從後到前依次放進stack,然後再次調用next方法。

hasNext,由於會出現stack不爲空,但是NestInteger爲{}的情況,需要先調用next得到返回的結果不爲null,再返回true,同時把返回的結果放到nextInteger裏面,next方法優先返回nextInteger,然後清空這個字段

package pid341;

import java.util.Iterator;
import java.util.List;
import java.util.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> {
	
	private Stack<NestedInteger> stack = new Stack<>();
	
	// 如果調用了hasNext方法,會把下一次返回的結果存在裏面,next方法會返回這個結果,並清空這個字段
	Integer nextInteger = null;

    public NestedIterator(List<NestedInteger> nestedList) {
    	if(nestedList.size() == 0){
    		return;
    	}
        for(int i=nestedList.size()-1;i>=0;i--){
        	stack.push(nestedList.get(i));
        }
    }

    @Override
    public Integer next() {
    	if(nextInteger != null){
    		Integer result = nextInteger;
    		nextInteger = null;
    		return result;
    	}
    	if(stack.isEmpty()){
    		return null;
    	}
    	NestedInteger now = stack.pop();
    	if(now.isInteger()){
    		return now.getInteger();
    	}else{
    		List<NestedInteger> nestedList = now.getList();
    		if(nestedList.size() != 0){
    			for(int i=nestedList.size()-1;i>=0;i--){
                	stack.push(nestedList.get(i));
                }
        	}   		
    		return next();
    	}
    }

    @Override
    public boolean hasNext() {       
    	if(stack.isEmpty()){
    		return false;
    	}else{
    		Integer now = next();
    		if(now==null){
    			return false;
    		}else{
    			nextInteger = now;
    			return true;
    		}
    	}
    }
}

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

 

解法2(別人的)

簡單粗暴,在初始化迭代器的時候就直接把結果遍歷出來,遞歸遍歷列表中的數據,是整數就放入List,不是則再遞歸遍歷,代碼結構簡單。

public class NestedIterator implements Iterator<Integer> {

    private List<Integer> list;
    private int index;

    public NestedIterator(List<NestedInteger> nestedList) {
        list = integerIterator(nestedList);
        index = -1;
    }

    @Override
    public Integer next() {
        if (this.hasNext())  return list.get(++index);
        return null;
    }

    @Override
    public boolean hasNext() {
        if (index + 1 < list.size()) return true;
        return false;
    }

    private static List<Integer> integerIterator(List<NestedInteger> nestedIntegerList) {
        ArrayList<Integer> list = new ArrayList<>(nestedIntegerList.size());
        for (NestedInteger tmp : nestedIntegerList) {
            if (tmp.isInteger()) 
                list.add(tmp.getInteger());
            else 
                list.addAll(integerIterator(tmp.getList()));
        }
        return list;
    }
}

解法3(別人的)

在類中添加nestedList、stack、iteratot、integer四個屬性,分別對應嵌套列表、迭代器存儲棧、當前迭代器、當前遍歷整數

構造函數初始化nestedList、iterator,iterator對應的就是構造參數的迭代器。

重寫hasNext()函數,主要邏輯爲:

    當前迭代器若hasNext()爲true
        判斷next()是否爲整數,若爲整數則賦值integer,返回``true`
        判斷next()是否爲列表,則將當前迭代器暫存至stack,並更新iterator爲當前列表的迭代器,遞歸hasNext()函數

    當前迭代器若hasNext()爲false且stack非空,則迭代器出棧更新爲當前iterator,遞歸hasNext()函數

    其他情況則代表,整個扁平化嵌套列表已遍歷完畢,返回false

重寫next()函數,迭代器的使用規則是hasNext()返回爲true時調用next()函數獲取下一值,再次直接返回integer(當前遍歷整數)即可。

public class NestedIterator implements Iterator<Integer> {
		//嵌套列表
  		private  List<NestedInteger> nestedList = null;
        //迭代器存儲棧
    	private Stack<Iterator<NestedInteger>> stack = new Stack<>();
    	//當前迭代器
        private Iterator<NestedInteger> iterator = null;
    	//當前遍歷整數
        private Integer integer = 0;
        public NestedIterator(List<NestedInteger> nestedList) {
            //嵌套列表初始化
            this.nestedList = nestedList;
            iterator = nestedList.iterator();
        }

        @Override
        public Integer next() {
            return integer;
        }

        @Override
        public boolean hasNext() {
            if(iterator.hasNext()) {
                NestedInteger nestedInteger = iterator.next();
                if (!nestedInteger.isInteger()) {
                    //該值爲列表
                    stack.push(iterator);
                    iterator = nestedInteger.getList().iterator();
                    return hasNext();
                } else {
                    integer = nestedInteger.getInteger();
                    return true;
                }
            }else if(!iterator.hasNext() && !stack.isEmpty()) {
                //當前迭代器至列表末尾並且棧非空
                //迭代器更新爲上一級
                iterator = stack.pop();
                return hasNext();
            }else{
                return false;
            }
        }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章