层序遍历:即分层遍历,卡哥的层序遍历的链接:代码随想录
层序遍历 10 道题
102.层序遍历: 题目链接:. - 力扣(LeetCode)
实现思路:限定当前层的数量的长度,进行遍历,并在此长度下,获取当前层的元素的集合暂存到层数组里,以及当前层的下一层的左右子节点
实现代码:应该是队列,取名有点问题
var levelOrder = function(root) {
if(root === null) return []
let result = [],stack = [];
stack.push(root)
while(stack.length) {
let size = stack.length
let lay_result = []
for(let i = 0; i < size; i = i + 1) {
let cur = stack.shift()
lay_result.push(cur.val)
cur.left && stack.push(cur.left)
cur.right && stack.push(cur.right)
}
result.push(lay_result)
}
return result
};
07.二叉树的层次遍历 II
题目链接:. - 力扣(LeetCode)
将上题结果反转,暂不赘述;
199.二叉树的右视图
该题是将二叉树的从右侧看到的节点都遍历出来,我的思路是取每层节点的最后一个节点,放入这个结果数组里;
实现代码:
var rightSideView = function(root) {
if(root === null) return []
let queue = [], result = []
queue.push(root)
while(queue.length) {
let size = queue.length;
let lay_result = []
for(let i = 0; i < size; i = i + 1) {
let cur = queue.shift()
lay_result.push(cur.val)
cur.left && queue.push(cur.left)
cur.right && queue.push(cur.right)
}
let lastEle = lay_result.pop()
result.push(lastEle)
}
return result
};
需要该层累加值和 size, 遍历过程和以上类似
function average(arr) {
if(arr.length === 0)return 0
const sum = arr.reduce((accu, current) => accu + current,0)
let size = arr.length;
return sum / size
}
需要遍历 children 的所有节点来获取层序遍历的值
var levelOrder = function (root) {
if (root === null) return []
let queue = [], result = []
queue.push(root)
while (queue.length) {
let size = queue.length;
let lay_result = []
for (let i = 0; i < size; i = i + 1) {
let cur = queue.shift()
lay_result.push(cur.val)
for (let i = 0; i < cur.children.length; i = i + 1) {
if (cur.children[i]) {
queue.push(cur.children[i])
}
}
}
result.push(lay_result)
}
return result
};
思路:代码
var largestValues = function(root) {
if(root === null) return []
let queue = [], result = []
queue.push(root)
while(queue.length) {
let size = queue.length;
let lay_result = 0
for(let i = 0; i < size; i = i + 1) {
let cur = queue.shift()
lay_result = Math.max(lay_result, cur.val)
cur.left && queue.push(cur.left)
cur.right && queue.push(cur.right)
}
result.push(lay_result)
}
return result
};
思路:同样是要分层遍历,区别在于这里只建立联系,并不另外生成数组
var connect = function(root) {
if(!root) return null
let queue = []
queue.push(root)
while(queue.length) {
let size = queue.length;
for(let i = 0; i < size; i = i + 1) {
let cur = queue.shift()
if(i < size - 1) {
cur.next = queue[0]
}
cur.left && queue.push(cur.left)
cur.right && queue.push(cur.right)
}
}
return root
};
同上题,区别在于二叉树的种类,但其实没有区别
思路:这里我的理解,深度即是二叉树的层数,所以直接返回层序遍历结果的数组长度
思路:这里我理解,判断子节点没有左节点和右节点时,即返回当前层序遍历的数组长度 + 1(+当前子节点的层数)
262. 翻转二叉树
题目链接:. - 力扣(LeetCode)
思路:层序遍历:每次push 入下一层节点时,将这一层的节点进行交换
var invertTree = function(root) {
if(!root) return null
let queue = []
queue.push(root)
while(queue.length) {
let size = queue.length;
for(let i = 0; i < size; i = i + 1) {
let cur = queue.shift()
// 翻转当前节点的左右节点
reverse(cur)
cur.left && queue.push(cur.left)
cur.right && queue.push(cur.right)
}
}
return root
};
function reverse(cur) {
let temp = cur.left
cur.left = cur.right
cur.right = temp
}
卡哥的递归方法: 前序和后序均可,中序遍历两次都需要递归左节点,因为如果中间节点交换放在中间的话,子节点已经交换过一次了,再递归右节点会存在一个节点没有被交换到
var invertTree = function(root) {
if(root === null) return root
swap(root)
invertTree(root.left)
invertTree(root.right)
return root
};
function swap(cur) {
let temp = cur.left
cur.left = cur.right
cur.right = temp
}
101. 对称二叉树
题目链接:. - 力扣(LeetCode)
思路:用层序遍历,这里的 null 也要 push 进数组
var isSymmetric = function (root) {
if (!root) return false
let queue = []
queue.push(root)
while (queue.length) {
let size = queue.length;
let lay_result = []
for (let i = 0; i < size; i = i + 1) {
let cur = queue.shift()
if (cur) {
lay_result.push(cur.val)
queue.push(cur.left)
queue.push(cur.right)
} else {
lay_result.push(null)
}
}
if (!isSymmetry(lay_result)) {
return false
}
}
return true
};
function isSymmetry(stack) {
let left = 0, right = stack.length - 1;
while (left < right) {
if (stack[left] !== stack[right]) {
return false
}
left = left + 1;
right = right - 1
}
return true
}