这是我参与8月更文挑战的第26天,活动详情查看:8月更文挑战
二叉树的镜像
剑指Offer 27.二叉树的镜像
难度:简单
请完成一个函数,输入一个二叉树,该函数输出它的镜像。
例如输入:
4
/ \
2 7
/ \ / \
1 3 6 9
镜像输出:
4
/ \
7 2
/ \ / \
9 6 3 1
示例1:
输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]
限制:0 <= 节点个数 <= 1000
题解
递归法
镜像,即从上到下,依次交换每个节点的左右节点。
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {TreeNode}
*/
var mirrorTree = function(root){
if(!root) return null;
// 交换当前节点的左右节点
const leftNode = root.left; // 声明临时变量存储左节点
root.left = root.right;
root.right = leftNode;
// 对左右子树做相同操作
mirrorTree(root.left);
mirrorTree(root.right);
return root;
}
或
/*
* 声明临时变量temp存储root的左子节点left
* 递归右子节点,将返回值赋给root的左子节点
* 递归左子节点,将返回值赋给root的右子节点
*/
var mirrorTree = function(root){
if(!root) return root;
var temp = root.left;
root.left = mirrorTree(root.right);
root.right = mirrorTree(temp);
return root;
}
或
var mirrorTree = function(root){
if(!root) return null;
[root.left,root.right] = [mirrorTree(root.right),mirrorTree(root.left)];
return root;
}
或
var mirrorTree = function(root) {
return root == null ? null : new TreeNode(root.val, mirrorTree(root.right), mirrorTree(root.left));
};
对称的二叉树
剑指Offer 28.对称的二叉树
难度:简单
请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它就是对称的。
例如:二叉树[1,2,2,3,4,4,3]是对称的。
1
/ \
2 2
/ \ / \
3 4 4 3
但是下面这个[1,2,2,null,3,null,3]则不是镜像对称的:
1
/ \
2 2
\ \
3 3
示例1:
输入:root = [1,2,2,3,4,4,3]
输出:true
示例2:
输入:root = [1,2,2,null,3,null,3]
输出:false
限制:0 <= 节点个数 <= 1000
题解
DFS
递归检查左右子树,在递归到下一层时,要同时检查左子树的左和右子树的右:check(left.left,right,right) && check(left.right,right.left)
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {boolean}
*/
var isSymmetric = function(root){
if(!root) return true;
var check = function(left,right){
if(!left && !right) return true; // 左右子树同时为空,则为镜像
if(!left || !right) return false;// 左右子树有一个为空,则不为镜像
return left.val === right.val && check(left.left,right.right) && check(left.right,right.left);
}
return check(root.left,root.right)
}
顺时针打印矩阵
剑指Offer 29.顺时针打印矩阵
难度:简单
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
示例1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
示例2:
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]
限制:
- 0 <= matrix.length <= 100
- 0 <= matrix[i].length <= 100
题解
顺时针方向像剥洋葱那样将矩阵一层一层剥掉,其中flag用来切换方向。
/**
* @param {number[][]} matrix
* @return {number[]}
*/
var spiralOrder = function(matrix){
var res = [];
var flag = true;
while(matrix.length){
// 从左到右
if(flag){
// 第一层
res = res.concat(matrix.shift());
// ‘现在’的第一层到最后一层的末尾
for(let i = 0;i < matrix.length;i++){
matrix[i].length && res.push(matrix[i].pop());
};
}else{// 从右到左
// 最后一层
res = res.concat(matrix.pop().reverse());
// '现在'的最后一层到第一层
for(let i = matrix.length - 1;i > 0;i--){
matrix[i]/length && res.push(matrix[i].shift());
}
}
flag = !flag;
}
return res;
}
包含min函数的栈
剑指Offer 30.包含min函数的栈
难度:简单
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数在栈中,调用min、push及pop的时间复杂度都是O(1)。
示例:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.min(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.min(); --> 返回 -2.
提示:各函数的调用总次数不超过20000次
题解
据题意,需要在O(1)时间找到最小值,这意味着我们不能在寻找最小值的时候,再做排序,查找等操作去获取。
法一 辅助栈法
可以采用空间换时间的原则,创建两个栈,一个栈是主栈stack,另一个是辅助栈minStack,用于存放对应主栈不同时期的最小值。
/**
* initialize your data structure here.
*/
var MinStack = function() {
this.stack = [];
this.minStack = [];
};
/**
* @param {number} x
* @return {void}
*/
MinStack.prototype.push = function(x) {
this.stack.push(x);
// 保持主栈和辅助栈同步,在辅助栈中,存放着每一位主栈元素对应的最小值
this.minStack.push(Math.min(this.minStack[this.minStack.length - 1], x));
};
/**
* @return {void}
*/
MinStack.prototype.pop = function() {
this.stack.pop();
this.minStack.pop();
};
/**
* @return {number}
*/
MinStack.prototype.top = function() {
return this.stack[this.stack.length - 1];
};
/**
* @return {number}
*/
MinStack.prototype.min = function() {
return this.minStack[this.minStack.length - 1];
};
/**
* Your MinStack object will be instantiated and called as such:
* var obj = new MinStack()
* obj.push(x)
* obj.pop()
* var param_3 = obj.top()
* var param_4 = obj.min()
*/
法二 迭代
其实挺类似辅助栈法的,迭代法是通过在栈里面存储进一个对象「x,min」的方式,在每一次对栈往里存或者弹出都要保持「x,min」同步,每一个对象中都存放着对应的最小值。
var MinStack = function() {
this.stack = [];
};
MinStack.prototype.push = function(x) {
this.stack.push({
x,min: this.stack.length ? Math.min(this.head().min,x) : x
});
};
MinStack.prototype.pop = function() {
this.stack.pop();
};
MinStack.prototype.top = function() {
return this.head().x;
};
MinStack.prototype.min = function() {
return this.head().min;
};
// 当前栈的最后一项 即栈顶头 head
MinStack.prototype.head = function(){
return this.stack[this.stack.length - 1];
}
坚持每日一练!前端小萌新一枚,希望能点个赞哇~