这是今天美团一面的手撕,面试时没有做出来,现在好好了解一下这道题。
所谓S型遍历,其实就是换一个顺序再遍历。如图所示:
那么我们使用什么来颠倒每次遍历的顺序呢?就是栈,两个栈。
(1)首先:将root放入1号栈中
(2)将1号中元素从栈中取出以后,再将子节点放入2号栈中,怎么使第二层的节点逆序遍历?那就顺序将其放进栈中
(3)那怎么将第三行再顺序遍历呢? 那就是按照7654入栈对吧,那按照第二层出栈顺序32,7654其实就是按照出栈元素的右左顺序入栈。如图。
(4)到这里我们看出所谓的S型遍历其实就变成了入栈顺序的变化 ,也就是没换一层,左右子节点的入栈顺序就变一次,所以我们固定1号栈就是逆序(右左)入栈,2号栈顺序(左右)入栈就实现了该题。
代码:
public List<Integer> sLevelOrder(TreeNode root){
List<Integer> res = new ArrayList<>();
if (root == null){
return res;
}
// 新建两个栈
Stack<TreeNode> stack1 = new Stack<>();
Stack<TreeNode> stack2 = new Stack<>();
stack1.push(root);
while(stack1.size() != 0 || stack2.size() != 0){
if (!stack1.empty()){
int size1 = stack1.size();
for (int i = 0; i < size1; i ++){
TreeNode node = stack1.pop();
res.add(node.val);
if (node.left != null) stack2.push(node.left);
if (node.right != null) stack2.push(node.right);
}
} else if (!stack2.empty()){
int size2 = stack2.size();
for (int i = 0; i < size2; i ++){
TreeNode node = stack2.pop();
res.add(node.val);
if (node.right != null) stack1.push(node.right);
if (node.left != null) stack1.push(node.left);
}
}
}
return res;
}
运行结果:
本题结束