这是我参与8月更文挑战的第27天,活动详情查看:8月更文挑战
栈的压入、弹出序列
剑指Offer 31.栈的压入、弹出序列
难度:中等
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列{1,2,3,4,5}是某栈的压栈序列,序列{4,5,3,2,1}是该压栈序列对应的一个弹出序列,但{4,3,5,1,2}就不可能是该压栈序列的弹出序列。
示例1:
输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
输出:true
解释:我们可以按以下顺序执行:
push(1), push(2), push(3), push(4), pop() -> 4,
push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1
示例2:
输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
输出:false
解释:1 不能在 2 之前弹出。
提示:
- 0 <= pushed.length == popped.length <= 1000
- 0 <= pushed[i],popped[i] < 1000
- pushed是popped的排列
题解
辅助栈
构造一个辅助栈来stack模拟压栈序列pushed的出栈,主要步骤如下:
- 入栈:按照压栈序列pushed的顺序入栈。
- 出栈:每次出栈后,需要循环判断stack的栈顶是否等于弹出序列popped的当前元素,将符合弹出序列顺序popped的栈顶全部弹出。
/**
* @param {number[]} pushed
* @param {number[]} popped
* @return {boolean}
*/
var validateStackSequences = function(pushed,popped){
// 辅助栈
const stack = [];
// 指向popped当前的下标
let index = 0;
// 把pushed的元素一个个入栈
for(let i = 0,len = pushed.length - 1;i <= len;i++){
stack.push(pushed[i]);
// 把入栈的当前元素和popped当前指向的元素进行对比
// 相等的话就把辅助栈出栈
// popped下标往右移动
while(stack.length > 0 && stack[stack.length - 1] === popped[index]){
stack.pop();
index++;
}
}
return !stack.length;
}
从上到下打印二叉树
剑指Offer 32 - I.从上到下打印二叉树
难度:中等
从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
例如:给定二叉树:[3,9,20,null,null,15,7]
3
/ \
9 20
/ \
15 7
返回:
[3,9,20,15,7]
提示:节点总数 <= 1000
题解
层序遍历
使用一个队列来存储有用的节点。步骤如下:
- 将root放入队列
- 取出队首元素,将val放入返回的数组中
- 取出队首元素的子节点,若不为空,则将子节点放入队列
- 检查队列是否为空,为空则返回数组;否则,回到第二步
JS中的队列都是使用数组来实现:
- 入队:queue.push(val)
- 出队:queue.shift()
- 检查是否为空:!!queue.length
- 查看队首元素:queue[0]
/**
* @param {TreeNode} root
* @return {number[]}
*/
var levelOrder = function(root){
if(!root){
return [];
}
const data = [];
const queue = [root]; // 队列
while(queue.length){
const head = queue.shift(); // 出队
data.push(head.val);
head.left && queue.push(head.left); // 入队
head.right && queue.push(head.right);// 入队
}
return data;
}
时间复杂度O(n)、空间复杂度O(n)
从上到下打印二叉树 ||
剑指Offer 32 - II.从上到下打印二叉树 II
难度:中等
从上到下按层打印二叉树,同一层的节点按照从左到右的顺序打印,每一层打印到一行。
例如:给定二叉树:[3,9,20,null,null,15,7]
3
/ \
9 20
/ \
15 7
返回:
[
[3],
[9,20],
[15,7]
]
提示:节点总数 <= 1000
题解
层序遍历
与上题《剑指Offer 32 - I.从上到下打印二叉树》类似,步骤如下:
- 将root放入队列
- 创建data用于存放返回的结果、level代表层树。
- 检查queue是否为空
- 不为空,依次遍历当前queue内所有节点,检查每个节点的左右子节点,如果左右子节点不为空,则继续将其放入queue,继续循环
- 为空,则跳出循环
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var levelOrder = function(root) {
if(!root) return [];
const queue = [root];
const data = []; // 存放遍历结果
let level = 0; // 代表当前层数
while(queue.length){
data[level] = []; // 第level层的遍历结果
let levelNum = queue.length;// 第level层的节点数量(例子中每层分别的节点数量为1、2、2)
while(levelNum--){
const head = queue.shift();
data[level].push(head.val);
head.left && queue.push(head.left);
head.right && queue.push(head.right);
}
level++;
}
return data;
};
时间复杂度O(N)、空间复杂度O(N)
从上到下打印二叉树 III
剑指Offer 32 - III.从上到下打印二叉树 III
难度:中等
请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到后的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。
例如:给定二叉树:[3,9,20,null,null,15,7]
3
/ \
9 20
/ \
15 7
返回:
[
[3],
[20,9],
[15,7]
]
提示:节点总数 <= 1000
题解
层序遍历
与上题《剑指Offer 32 - II.从上到下打印二叉树 II》类似,步骤如下:
- 将root放入队列
- 创建data用于存放返回的结果、level代表层树。
- 检查queue是否为空
- 不为空,依次遍历当前queue内所有节点,检查每个节点的左右子节点,如果左右子节点不为空,则继续将其放入queue,继续循环;再其后面加上判断层数是否为偶数,为偶数则将那一层的结果做倒序处理。
- 为空,则跳出循环
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var levelOrder = function(root) {
if(!root) return [];
const queue = [root];
const data = []; // 存放遍历结果
let level = 0; // 代表当前层数
while(queue.length){
data[level] = []; // 第level层的遍历结果
let levelNum = queue.length;// 第level层的节点数量(例子中每层分别的节点数量为1、2、2)
while(levelNum--){
const head = queue.shift();
data[level].push(head.val);
head.left && queue.push(head.left);
head.right && queue.push(head.right);
}
if(level % 2===1){ // level是从0开始的,所以level为1时,对应的是第二层
data[level].reverse();
}
level++;
}
return data;
};
时间复杂度O(N)、空间复杂度O(N)
坚持每日一练!前端小萌新一枚,希望能点个赞
哇~