一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第20天,点击查看活动详情。
31、栈的压入和弹出序列
题目:给定两个整数序列,第一个序列表示栈的压入顺序,要求判断第二个序列是否是第一个栈的弹出顺序。已知栈中所有元素都不同。
解题思路
本题实际上很简单,既然给了入栈顺序和出栈顺序,那么根据这两个序列进行模拟一下入栈和出栈的顺序即可,即:
- 初始化标记索引,标记索引指向序列二的第一个元素,之后根据序列一先入栈。
- 判断栈顶元素是否为序列二的标记索引的值,如果是则出栈,否则入栈。
- 循环第二步,直到栈空或栈顶元素和序列二标记索引元素不相等。
- 循环步骤1、2、3。
- 如果满足最终的栈为空,则序列二必定是满足第一个栈的出栈顺序。
根据此逻辑可得代码:
public boolean validateStackSequences(int[] pushed, int[] popped) {
int cur = 0;
Stack<Integer> stack = new Stack<>();
for(int i=0;i<pushed.length;i++){
stack.push(pushed[i]);
while(!stack.isEmpty()&&popped[cur] == stack.peek()){
cur++;
stack.pop();
}
}
return stack.isEmpty()&&cur==popped.length;
}
32、从上向下打印二叉树
题目:给定一颗二叉树,要求从上到下打印二叉树的每个节点,同一层中的节点按照从左向右的顺序打印。
解题思路
本题实际上就是二叉树的层序遍历,使用队列即可完成本题,每次遍历到一个节点的时候,都将节点的左右孩子放入队列,可得如下代码:
public int[] levelOrder(TreeNode root) {
ArrayList<Integer> res = new ArrayList<>();
if(root == null) return new int[0];
ArrayDeque<TreeNode> queue = new ArrayDeque<>();
queue.offer(root);
while(!queue.isEmpty()){
TreeNode node = queue.poll();
res.add(node.val);
if(node.left!=null) queue.offer(node.left);
if(node.right!=null) queue.offer(node.right);
}
return res.stream().mapToInt(Integer::valueOf).toArray();
}
上述在将ArrayList转为数组的时候使用了Java8的新特性Stream。实际上此操作十分耗时,不如循环复制来的快,可采用如下方式循环赋值得到最终结果:
int[] result = new int[res.size()];
for(int i=0;i<res.size();i++){
result[i] = res.get(i);
}
return result;