題目及測試
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;
}
}
}