Flatten Nested List Iterator (M)

题目

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:

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

Example 2:

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

题意

给定一个任意嵌套的整数列表,要求按顺序输出所有整数。

思路

迭代处理:用两个栈分别取存储暂时挂起的列表和对应的下标,每当遇到一个嵌套列表时,就把当前列表和下标压栈,进入嵌套列表继续处理;当当前列表已经遍历完时,则出栈之前的列表和下标继续处理。

也可直接用递归展开。


代码实现

Java

迭代处理

  1. public class NestedIterator implements Iterator<Integer> {
  2. private Deque<List<NestedInteger>> lists = new ArrayDeque<>();
  3. private Deque<Integer> indices = new ArrayDeque<>();
  4. private List<NestedInteger> list;
  5. private int index;
  6. private Integer num;
  7. public NestedIterator(List<NestedInteger> nestedList) {
  8. list = nestedList;
  9. index = -1;
  10. generate();
  11. }
  12. @Override
  13. public Integer next() {
  14. Integer res = num;
  15. generate();
  16. return res;
  17. }
  18. @Override
  19. public boolean hasNext() {
  20. return num != null;
  21. }
  22. private void generate() {
  23. index++;
  24. while (index < list.size() || !lists.isEmpty()) {
  25. if (index == list.size()) {
  26. list = lists.pop();
  27. index = indices.pop() + 1;
  28. } else if (!list.get(index).isInteger()) {
  29. lists.push(list);
  30. indices.push(index);
  31. list = list.get(index).getList();
  32. index = 0;
  33. } else {
  34. break;
  35. }
  36. }
  37. num = index < list.size() ? list.get(index).getInteger() : null;
  38. }
  39. }

递归展开

  1. public class NestedIterator implements Iterator<Integer> {
  2. List<Integer> list = new ArrayList<>();
  3. int index = 0;
  4. public NestedIterator(List<NestedInteger> nestedList) {
  5. generate(nestedList);
  6. }
  7. @Override
  8. public Integer next() {
  9. return list.get(index++);
  10. }
  11. @Override
  12. public boolean hasNext() {
  13. return index != list.size();
  14. }
  15. private void generate(List<NestedInteger> nestedList) {
  16. for (NestedInteger item : nestedList) {
  17. if (item.isInteger()) {
  18. list.add(item.getInteger());
  19. } else {
  20. generate(item.getList());
  21. }
  22. }
  23. }
  24. }

JavaScript

  1. /**
  2. * @constructor
  3. * @param {NestedInteger[]} nestedList
  4. */
  5. var NestedIterator = function (nestedList) {
  6. this.list = flatten(nestedList)
  7. this.index = 0
  8. }
  9. /**
  10. * @this NestedIterator
  11. * @returns {boolean}
  12. */
  13. NestedIterator.prototype.hasNext = function () {
  14. return this.index < this.list.length
  15. }
  16. /**
  17. * @this NestedIterator
  18. * @returns {integer}
  19. */
  20. NestedIterator.prototype.next = function () {
  21. return this.list[this.index++]
  22. }
  23. function flatten(nestedList) {
  24. let flattened = []
  25. for (const item of nestedList) {
  26. if (item.isInteger()) flattened.push(item.getInteger())
  27. else flattened = flattened.concat(flatten(item.getList()))
  28. }
  29. return flattened
  30. }