坚持按题型打卡&刷&梳理力扣算法题系列,语言为go,Day16
相同的树
- 题目描述
- 解题思路
- 边界条件,其中一个节点为空,return 只有p和q均为空才返回true,因此可以简写为p==q
- return,先判断节点值是否一样,然后递归判断左子树是否一样,然后递归判断右子树是否一样
- 代码参考
go
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func isSameTree(p *TreeNode, q *TreeNode) bool {
if p == nil || q == nil{ // 只要有一个为空就return
return p == q
}
return p.Val == q.Val && isSameTree(p.Left,q.Left) && isSameTree(p.Right,q.Right)
}
- tips
- 注意空节点的return条件,只要左或者右有一个为空就返回,p和q必须都是nil才能返回true
- 比较的时候,需要同时比较p和q的左子树,以及p和q的右子树
对称二叉树
- 题目描述
- 解题思路
- 在上一题的基础上稍加改动
- 代码参考
go
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func isSameTree(p *TreeNode, q *TreeNode) bool{
if p==nil || q==nil{
return p==q
}
return p.Val == q.Val && isSameTree(p.Left,q.Right) && isSameTree(p.Right,q.Left)
}
func isSymmetric(root *TreeNode) bool {
return isSameTree(root.Left,root.Right)
}
- tips
- 转换为比较左边的右子树是否等于右边的左子树,左边的左子树是否等于右边的右子树即可
- 转换为比较左边的右子树是否等于右边的左子树,左边的左子树是否等于右边的右子树即可
平衡二叉树
- 题目描述
- 解题思路
- 对左右子树的深度做递归
- 代码参考
go
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func abs(x int) int{
if x>0{
return x
}else{
return -x
}
}
func get_height(root *TreeNode) int{
if root == nil{
return 0
}
left_height := get_height(root.Left)
if left_height == -1{
return -1 //提前退出,不再递归
}
right_height := get_height(root.Right)
if right_height == -1 || abs(right_height - left_height)>1{
return -1
}
return max(right_height,left_height)+1
}
func isBalanced(root *TreeNode) bool {
if get_height(root) != -1{
return true
}else{
return false
}
}
- tips
- 需要单独写一个获取树的最大深度的get_height函数
- go中没有abs函数,需要自己写
- -1表示不平衡,可以实现提前退出,就不用递归了
二叉树的右视图
-
题目描述
-
解题思路
- 因为要找右视图,所以先递归右子树,再递归左子树
- 怎么判断节点是否需要记录到答案中
- 在递归的同时记录节点个数(也就是递归深度),如果递归深度等于答案长度,那么这个节点就需要记录到答案中
- 递归左子树的时候,深度小于答案长度的就都不计进去
-
代码参考
go
func rightSideView(root *TreeNode) (ans []int) {
//声明 dfs 为一个函数变量: var dfs func(*TreeNode, int) 声明了一个名为 dfs 的变量,这个变量的类型是一个函数类型。
var dfs func(*TreeNode, int)
// 这样,dfs 就可以像普通函数一样被调用,并且在函数体内部它可以递归调用自身。在这里我们可以直接在一个函数内部定义 DFS 逻辑,而不需要创建一个单独的命名函数。
dfs = func(node *TreeNode, depth int) {
if node == nil {
return
}
if depth == len(ans) { // 这个深度首次遇到
ans = append(ans, node.Val)
}
dfs(node.Right, depth+1) // 先递归右子树,保证首次遇到的一定是最右边的节点
dfs(node.Left, depth+1)
}
dfs(root, 0)
return
}
- tips
- 声明 dfs 为一个函数变量: var dfs func(*TreeNode, int) 声明了一个名为 dfs 的变量,这个变量的类型是一个函数类型。
- 这样,dfs 就可以像普通函数一样被调用,并且在函数体内部它可以递归调用自身。在这里我们可以直接在一个函数内部定义 DFS 逻辑,而不需要创建一个单独的命名函数。