2021-06-13:如果一个节点X,它左树结构和右树结构完全一样,那么我们说以X为头的树是相等树。给定一棵二叉树的头节点head,返回head整棵树上有多少棵相等子树。
2021-06-13:如果一个节点X,它左树结构和右树结构完全一样,那么我们说以X为头的树是相等树。给定一棵二叉树的头节点head,返回head整棵树上有多少棵相等子树。
福大大 答案2021-06-14:
方法一:自然智慧。
递归函数:头num=左num+右num+0或1。
相等判断函数:左结构=右结构,O(N)。
树越不平衡,复杂度越低,因此算复杂度的时候,只需要考虑平衡树。
master公式:T(N)=2T(N/2)+O(N)。2T(N/2)是递归。O(N)是相等判断函数。
根据master公式,时间复杂度是O(N*logN)。
方法二:方法一的相等判断函数用哈希函数。
递归函数:头num=左num+右num+0或1。头哈希=【左哈希+头值+右哈希】的哈希值。这个递归有两个返回值。
相等判断函数:左结构=右结构,用哈希值判断,O(1)。
树越不平衡,复杂度越低,因此算复杂度的时候,只需要考虑平衡树。
master公式:T(N)=2T(N/2)+O(1)。2T(N/2)是递归。O(1)是相等判断函数。
根据master公式,时间复杂度是O(N)。
代码用golang编写。代码如下:
package main
import (
"crypto/md5"
"fmt"
)
func main() {
head := &Node{Val: 1}
head.Left = &Node{Val: 2}
head.Right = &Node{Val: 2}
head.Left.Left = &Node{Val: 3}
head.Left.Right = &Node{Val: 4}
head.Right.Left = &Node{Val: 3}
head.Right.Right = &Node{Val: 4}
ret1 := sameNumber1(head)
fmt.Println(ret1)
ret2 := sameNumber2(head)
fmt.Println(ret2)
}
type Node struct {
Val int
Left *Node
Right *Node
}
// 方法一:时间复杂度O(N * logN)
func sameNumber1(head *Node) int {
if head == nil {
return 0
}
return sameNumber1(head.Left) + sameNumber1(head.Right) + twoSelectOne(same(head.Left, head.Right), 1, 0)
}
func same(left *Node, right *Node) bool {
if left == nil && right == nil {
return true
}
if left == nil || right == nil {
return false
}
// 两个都不为空
return left.Val == right.Val && same(left.Left, right.Left) && same(left.Right, right.Right)
}
func twoSelectOne(c bool, a int, b int) int {
if c {
return a
} else {
return b
}
}
type Info struct {
ans int
str string
}
//方法二
func sameNumber2(head *Node) int {
return process2(head).ans
}
func process2(head *Node) *Info {
if head == nil {
return &Info{ans: 0, str: fmt.Sprintf("%x", md5.Sum([]byte("#,")))}
}
l := process2(head.Left)
r := process2(head.Right)
ans := twoSelectOne(l.str == r.str, 1, 0) + l.ans + r.ans
str := fmt.Sprintf("%x", md5.Sum([]byte(fmt.Sprintf("%d,%s%s", head.Val, l.str, r.str))))
return &Info{ans: ans, str: str}
}
执行结果如下:

2021-06-13:如果一个节点X,它左树结构和右树结构完全一样,那么我们说以X为头的树是相等树。给定一棵二叉树的头节点head,返回head整棵树上有多少棵相等子树。的更多相关文章
- 笔试算法题(36):寻找一棵二叉树中最远节点的距离 & 根据二叉树的前序和后序遍历重建二叉树
出题:求二叉树中距离最远的两个节点之间的距离,此处的距离定义为节点之间相隔的边数: 分析: 最远距离maxDis可能并不经过树的root节点,而树中的每一个节点都可能成为最远距离经过的子树的根节点:所 ...
- 二叉树中两节点的最近公共父节点(360的c++一面问题)
面试官的问题:写一个函数 TreeNode* Find(TreeNode* root, TreeNode* p, TreeNode* q) ,返回二叉树中p和q的最近公共父节点. 本人反应:当时有点 ...
- DOM节点树和元素树--深度遍历
我们在阅读JS高级程序设计的时候,提到了节点树的概念.比如说: elem.parentNode---找elem的父节点: elem.childNodes---找elem的所有的直接子节点: elem. ...
- 剑指offer17:输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
1 题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 2 思路和方法 (1)先在A中找和B的根节点相同的结点 (2)找到之后遍历对应位置的其他结点, ...
- java实现二叉树的Node节点定义手撕8种遍历(一遍过)
java实现二叉树的Node节点定义手撕8种遍历(一遍过) 用java的思想和程序从最基本的怎么将一个int型的数组变成Node树状结构说起,再到递归前序遍历,递归中序遍历,递归后序遍历,非递归前序遍 ...
- 探索未知种族之osg类生物---状态树与渲染树以及节点树之间的关系
节点树 首先我们来看一个场景构建的实例,并通过它来了解一下“状态节点”StateGraph 和“渲染叶”RenderLeaf 所构成的状态树,“渲染台”RenderStage 和“渲染元”Render ...
- leetcode 235 236 二叉树两个节点的最近公共祖先
描述: 给定二叉树两个节点,求其最近公共祖先.最近即所有公共祖先中深度最深的. ps:自身也算自身的祖先. 235题解决: 这是二叉搜索树,有序的,左边小右边大. TreeNode* lowestCo ...
- 【剑指offer】输入一颗二叉树的根节点,求二叉树的深度,C++实现
原创博文,转载请注明出处! # 题目 # 举例 下图二叉树的深度为4,最长路径为1-2-5-7. # 思路(递归) 如果一个树只有一个节点,它的深度为1: 如果根节点只有左子 ...
- 洛谷 P3384 【模板】树链剖分-树链剖分(点权)(路径节点更新、路径求和、子树节点更新、子树求和)模板-备注结合一下以前写的题目,懒得写很详细的注释
P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...
- linux设备驱动程序-设备树(3)-设备树多级子节点的转换
linux设备驱动程序--设备树多级子节点的转换 在上一章:设备树处理之--device_node转换成platform_device中,有提到在设备树的device_node到platform_de ...
随机推荐
- 华大单片机HC32L13X软件设计时候要注意的事项
1.系统启动时默认设置主频为内部4MHz; 2.调试超低功耗程序或者把SWD端口复用为GPIO功能都会把芯片的SWD功能关掉,仿真器将会与芯片失去连接,建议在main函数开始后加上1到2秒的延时,仿真 ...
- vue路由重复跳转导致控制台报错
重复跳转了同一个页面,导致空值台报错了! 解决思路: 方案1:在路由跳转时捕获错误. 1.1 全局捕获处理 //index.js import VueRouter from 'vue-router' ...
- 钉钉回调事件-asp.net core 开发钉钉回调事件
最近有一个钉钉的项目,所以,接下来的日子里,我会把钉钉开发中遇到的问题都整理成博客,供大家参考. 钉钉开发者后台,添加好了小程序,需要提供一个回调URL地址,用于数据的同步.如下图 根据钉钉提供的de ...
- 刷爆 LeetCode 双周赛 100,单方面宣布第一题最难
本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问. 大家好,我是小彭. 上周末是 LeetCode 第 100 场双周赛,你参加了吗?这场周赛整体没有 Hard ...
- CSAPP-Shell Lab
提供的工具: parseline:获取参数列表char **argv,返回是否为后台运行命令(true). clearjob:清除job结构. initjobs:初始化jobs链表. maxjid:返 ...
- Django笔记十二之defer、only指定返回字段
本篇笔记为Django笔记系列之十二,首发于公号[Django笔记] 本篇笔记将介绍查询中的 defer 和 only 两个函数的用法,笔记目录如下: defer only 1.defer defer ...
- 【深入浅出 Yarn 架构与实现】6-2 NodeManager 状态机管理
一.简介 NodeManager(NM)中的状态机分为三类:Application.Container 和 LocalizedResource,它们均直接或者间接参与维护一个应用程序的生命周期. 当 ...
- 基于Label studio实现UIE信息抽取智能标注方案,提升标注效率!
基于Label studio实现UIE信息抽取智能标注方案,提升标注效率! 项目链接见文末 人工标注的缺点主要有以下几点: 产能低:人工标注需要大量的人力物力投入,且标注速度慢,产能低,无法满足大规模 ...
- vue中实现video的动态src绑定
Vue中实现video的动态src 试了网上的$refs方法发现并没有用 解决方案: 通过require方法 <div> <video :src='url' @click= ...
- easy-excel读取远程地址获得文件进行上传
背景 作为一个快五年的程序员,一直以来还没有自己维护过自己的技术栈,最近也是有时间,所以也是下定决心,从头开始,一步一步的夯基础.最近在系统化的学习easy-excel,今天遇到了一个问题,特意记录一 ...