l--- highlight: a11y-dark
最近在leetcode上刷题,感觉到自己的功力还远远不够,尤其是对二叉树相关问题的求解,很多时候甚至连思路都不清晰,更不用说敲代码了
在刷了几道题后,也算是小有总结:
总体来说,可能是刷题类型的缘故,目前接触到的二叉树相关算法题,都需要使用递归,而通常递归的各种边界条件都十分难思考,可能还需要不断都学习以及总结。
个人认为,之所以二叉树问题求解都会涉及到递归,是因为二叉树与数组类型问题不同,无法通过输入直接判定方法的结束,并且和链表也不相同,无法仅通过一个循环将整个事件流程整理清楚,所以需要递归对不同方向上的链表进行分类讨论,最后获得想要的结果\
附刷题记录:
266.翻转二叉树
给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
solve:
let reverse = function(root){
if(!root) return null
let left = reverse(root.left)
let right = reverse(root.right)
root.left = right
root.right = left
return root
}
思路:
- 判断当前节点是否为空,是则返回null,说明已经走到叶子节点尽头
- 向左支递归
- 向右只递归
- 交换当前节点的左右只
- 返回当前节点
剑指 Offer 68 - II. 二叉树的最近公共祖先
solve:
let solve = function(root, p, q){
if(!root) return null
if(root.val===p.val||root.val===q.val) return root
let left = solve(root.left, p, q)
let right = solve(root.right, p, q)
if(left&&right) return root
return left || right
}
思路:
- 判断当前节点是否为空,是则返回null,说明已经走到叶子节点尽头
- 如果当前节点值为p或q,则返回当前节点
- 向左支递归
- 向右只递归
- 如果当前节点的左右递归结果不为空,说明就是目标节点,则返回当前节点
- 返回左递归或右递归结果
206. 反转链表
solve:
let reverse = function(root){
let pre = null,
cur = root
while(cur){
let nextNode = cur.next
cur.next = pre
pre = cur
cur = nextNode
}
return pre
}
思路:
- 从第一个节点开始,记录前一节点pre以及后一节点nextNode
- 当前节点的下一节点cur.next指向上一节点pre
- 将当前节点置为pre,下一节点置为cur
- 重复上述操作直至cur为null
- 此时pre即为原始链表的结尾,也就是反转后的链表开头
- 返回pre
234. 回文链表
solve:
let reverse = function(root){
let pre = null,
cur = root
while(cur){
let nextNode = cur.next
cur.next = pre
pre = cur
cur = nextNode
}
return pre
}
let isPalindrome = function(head){
let slow = fast = head
while(fast&&fast.next){
fast = fast.next.next
slow = slow.next
}
if(fast){
slow = slow.next
}
slow = reverse(slow)
while(slow){
if(head.val!==slow.val) return false
head = head.next
slow = slow.next
}
return true
}
543. 二叉树的直径
solve:
let diameterOfBinaryTree = function(root){
let ans = 0
function solve(root){
if(!root) return 0
let left = solve(root.left)
let right = solve(root.right)
//这里两结点之间的路径长度是以它们之间边的数目表示,所以不需要加1
ans = Math.max(left + right, ans)
return Math.max(left, right) + 1
}
return ans
}
剑指 Offer 55 - I. 二叉树的深度
solve:
//dfs
let maxDepth = function(root){
if(!root) return 0
let left = maxDepth(root.left)
let right = maxDepth(root.right)
return Math.max(left, right) + 1
}
//bfs
let maxDepth = function(root){
if(!root) return 0
let queue = [root], ans = 0
while(queue.length){
let len = queue.length
while(len){
let node = queue.shift()
if(node.left){
queue.push(node.left)
}
if(node.right){
queue.push(node.right)
}
len--
}
ans++
}
return ans
}