[随缘一题]平面列表

来源

来源:

lintcode-平面列表

描述

给定一个列表,该列表中的每个要素要么是个列表,要么是整数。将其变成一个只包含整数的简单列表。

样例

1
2
3
给定 [1,2,[1,2]],返回 [1,2,1,2]。

给定 [4,[3,[2,[1]]]],返回 [4,3,2,1]。

挑战

请用非递归方法尝试解答这道题。

解题思路

这道题一看就是用递归解决啦~,好,那我们就用递归.

啥玩意你不让用???

那可以用类似于二叉树的非递归遍历的思想,借用队列或者栈.

二叉树非递归遍历:

先将全部左节点入栈,然后拿出来一个,是叶子节点,则将其记录.不是叶子节点,则将其孩子节点入栈.

这道题也可以:
先将全部初始值全部入栈,然后拿出一个,如果是整数,则记录.如果是列表,则将其所有元素入栈.👌.

代码实现

NestedInteger的定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 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();
}

递归版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
public List<Integer> flatten1(List<NestedInteger> nestedList) {
List<Integer> result = new ArrayList<>();
for (int i = 0; i < nestedList.size(); i++) {
//是整数则添加到结果集
if (nestedList.get(i).isInteger()) {
result.add(nestedList.get(i).getInteger());
continue;
}
//是列表则递归调用将结果全添加到结果集中
result.addAll(flatten1(nestedList.get(i).getList()));
}
return result;
}

非递归版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public List<Integer> flatten2(List<NestedInteger> nestedList) {
List<Integer> result = new LinkedList<>();
Stack<NestedInteger> stack = new Stack<>();
//初始全部入栈
nestedList.forEach((stack::push));
while (!stack.isEmpty()) {
NestedInteger current = stack.pop();
if (current == null) {
continue;
}
//当前为整数则添加到结果集
if (current.isInteger()) {
((LinkedList<Integer>) result).addFirst(current.getInteger());
} else {
//否则遍历列表将元素全部入栈
current.getList().forEach(stack::push);
}
}
return result;
}

用栈来实现非递归版本的时候会有一个问题,拿到的结果是逆序的.因此在代码里使用了LinkedList.在添加的时候不断的addFirst,即在头部添加,这样返回改列表的时候,顺序与要求得一致.

完。




ChangeLog

2018-12-26 完成

以上皆为个人所思所得,如有错误欢迎评论区指正。

欢迎转载,烦请署名并保留原文链接。

联系邮箱:huyanshi2580@gmail.com

更多学习笔记见个人博客——>呼延十