102. 二叉树的层序遍历
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var levelOrder = function(root) {
let res = []
if(root===null) return res
let queue=[root] //队列
while(queue.length!==0){//当queue里没有数时
let temp=[] //这一维数组
let size=queue.length
while(size!==0){ //把此层弹出,并把他们的儿子多少个,并入队
let x = queue.shift() //弹出头部
temp.push(x.val) //此层弹入
if(x.left) queue.push(x.left) //下一层计数
if(x.right) queue.push(x.right)
size--
}
res.push(temp)
}
return res
};
思想
一层一层的遍历。
当我在计入此层(弹出)时,并把下一层的儿子入队。下一次遍历时,size=size=queue.length。计入此层该有的数量。
226.翻转二叉树
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {TreeNode}
*/
/***递归法*********************************************************/
//前序遍历
var invertTree = function(root) {
if(root!==null)
{
[root.left,root.right]=[root.right,root.left]
invertTree(root.left)
invertTree(root.right)
}
return root
};
//后序遍历
var invertTree = function(root) {
if (root == null) return null;
invertTree(root.left); //左
invertTree(root.right); //右
[root.left, root.right] = [root.right, root.left]; //中
return root;
};
//zhongxu
var invertTree = function(root) {
if (root == null) return null;
invertTree(root.left); //左
[root.left, root.right] = [root.right, root.left]; //中
invertTree(root,left); //右
return root;
};
法二:迭代法(前序遍历)
var invertTree = function(root) {
if (root == null) return null;
let st=[root] //栈
while(st.length){
let x=st.pop();
[x.left,x.right] = [x.right,x.left];
if(x.right) st.push(x.right)
if(x.left) st.push(x.left)
}
return root
}
法三:广度优先——层序遍历
var invertTree = function(root) {//一层一层的,从上往下翻转
let queue = [root]
if(!root) return null
while(queue.length){
let x = queue.shift();
[x.left,x.right] = [x.right,x.left];
if(x.right) queue.push(x.right)
if(x.left) queue.push(x.left)
}
return root
}
第一想法
把上面一道题得出的res翻转,但想复杂了
困难
理解过程,和写出代码
[x.left,x.right] = [x.right,x.left];前面要加 —— ;
收获
-
对前中后遍历熟系了,对深度和广度理解也深了
-
let x = queue.shift();这个只是对这个节点多取一个外号,没有新创内存
101. 对称二叉树
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {boolean}
*/
var eq = function (l,r){
if (l == null && r !== null) return false;
else if (l!== null && r === null) return false;
else if (l === null && r === null) return true;
// 排除了空节点,再排除数值不相同的情况
else if (l.val != r.val) return false;
// 此时就是:左右节点都不为空,且数值相同的情况
// 此时才做递归,做下一层的判断
var outside = eq(l.left, r.right); // 左子树:左、 右子树:右
var inside = eq(l.right, r.left); // 左子树:右、 右子树:左
var isSame = outside && inside; // 左子树:中、 右子树:中 (逻辑处理)
return isSame;
}
var isSymmetric = function(root) { //一个树上两个操作同时后序遍历
if(root===null)
return true
return eq(root.left,root.right)
};
队列(卡哥版本):
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if (root == NULL) return true;
queue<TreeNode*> que;
que.push(root->left); // 将左子树头结点加入队列
que.push(root->right); // 将右子树头结点加入队列
while (!que.empty()) { // 接下来就要判断这两个树是否相互翻转
TreeNode* leftNode = que.front(); que.pop();
TreeNode* rightNode = que.front(); que.pop();
if (!leftNode && !rightNode) { // 左节点为空、右节点为空,此时说明是对称的
continue;
}
// 左右一个节点不为空,或者都不为空但数值不相同,返回false
if ((!leftNode || !rightNode || (leftNode->val != rightNode->val))) {
return false;
}
que.push(leftNode->left); // 加入左节点左孩子
que.push(rightNode->right); // 加入右节点右孩子
que.push(leftNode->right); // 加入左节点右孩子
que.push(rightNode->left); // 加入右节点左孩子
}
return true;
}
};
栈:
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if (root == NULL) return true;
stack<TreeNode*> st; // 这里改成了栈
st.push(root->left);
st.push(root->right);
while (!st.empty()) {
TreeNode* leftNode = st.top(); st.pop();
TreeNode* rightNode = st.top(); st.pop();
if (!leftNode && !rightNode) {
continue;
}
if ((!leftNode || !rightNode || (leftNode->val != rightNode->val))) {
return false;
}
st.push(leftNode->left);
st.push(rightNode->right);
st.push(leftNode->right);
st.push(rightNode->left);
}
return true;
}
};
思想
递归(栈感觉就是递归的底层实现)
栈和队列其实差不多,把左右两个东西一起压入(判断)