文心一言 VS 讯飞星火 VS chatgpt (124)-- 算法导论10.5 5题
五、用go语言,给定一个n结点的二叉树,写出一个 O(n)时间的非递归过程,将该树每个结点的关键字输出。要求除该树本身的存储空间外只能使用固定量的额外存储空间,且在过程中不得修改该树,即使是暂时的修改也不允许。
文心一言:
您可以使用一个栈来存储节点,以便在遍历二叉树时进行回溯。由于您要求不能修改树的结构,我们需要在原树上进行操作。以下是一个可能的解决方案:
package main
import (
"fmt"
)
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func PrintTree(root *TreeNode) {
if root == nil {
return
}
stack := []*TreeNode{root}
for len(stack) > 0 {
node := stack[len(stack)-1]
stack = stack[:len(stack)-1]
fmt.Println(node.Val)
if node.Left != nil {
stack = append(stack, node.Left)
}
if node.Right != nil {
stack = append(stack, node.Right)
}
}
}
在这个函数中,我们首先检查根节点是否为空。如果为空,那么就直接返回。否则,我们将根节点放入栈中。然后,我们开始一个循环,只要栈不为空,就持续运行。在每个循环中,我们取出栈顶的节点,打印其值,然后依次将其左子节点和右子节点(如果存在)放入栈中。这样,我们就可以按照中序遍历的顺序打印出每个节点的值,而中序遍历是二叉树所有遍历方法中最接近线性时间的。同时,因为我们只使用了固定数量的额外存储空间(即栈的空间),所以满足了题目中的要求。
讯飞星火:
解析:
1.首先,我们需要创建一个二叉树节点的结构体,包含关键字和左右子节点的指针。
2.然后,我们需要创建一个非递归的过程来遍历二叉树。我们可以使用一个栈来实现这个过程。初始时,我们将根节点压入栈中。
3.在每一步中,我们从栈顶取出一个节点,输出它的关键字,然后将它的右子节点和左子节点(如果存在的话)压入栈中。这样,我们就可以按照先序遍历的顺序访问所有的节点。
4.重复这个过程,直到栈为空,也就是我们已经访问了所有的节点。
代码如下:
package main
import "fmt"
// 定义二叉树节点的结构体
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
// 非递归过程遍历二叉树并输出每个节点的关键字
func printTree(root *TreeNode) {
if root == nil {
return
}
stack := []*TreeNode{root}
for len(stack) > 0 {
node := stack[len(stack)-1]
stack = stack[:len(stack)-1]
fmt.Println(node.Val)
if node.Right != nil {
stack = append(stack, node.Right)
}
if node.Left != nil {
stack = append(stack, node.Left)
}
}
}
func main() {
// 创建一个简单的二叉树进行测试
root := &TreeNode{Val: 1}
root.Left = &TreeNode{Val: 2}
root.Right = &TreeNode{Val: 3}
root.Left.Left = &TreeNode{Val: 4}
root.Left.Right = &TreeNode{Val: 5}
printTree(root)
}
这段代码首先定义了一个二叉树节点的结构体,然后定义了一个非递归的过程来遍历二叉树并输出每个节点的关键字。在主函数中,我们创建了一个简单的二叉树进行测试。
360智脑:
以下是一个用Go语言实现的非递归遍历二叉树并输出每个结点的关键字的示例代码。这个代码使用了栈来辅助实现,因此时间复杂度为O(n)。
package main
import (
"fmt"
)
// 定义二叉树节点
type Node struct {
key int
left; *Node
right *Node
}
// 打印二叉树结点
func printTree(root *Node) {
if root == nil {
return
}
stack := []*Node{}
stack = append(stack, root)
for len(stack) > 0 {
node := stack[len(stack)-1]
stack = stack[:len(stack)-1]
fmt.Printf("Node: %d\n", node.key)
// 弹出左子节点和右子节点
if node.left != nil {
stack = append(stack, node.left)
}
if node.right != nil {
stack = append(stack, node.right)
}
}
}
// 定义主函数
func main() {
// 创建二叉树
root := &Node{key: 100}
root.left = &Node{key: 50}
root.right = &Node{key: 300}
root.left.left = &Node{key: 20}
root.left.right = &Node{key: 40}
// 打印结点
printTree(root)
}
在这个代码中,我们使用了一个栈来存储待处理的二叉树的节点。每次取出一个节点,然后弹出它的左右子节点,并将这些节点存储在一个新的栈中。这样,我们就可以在不修改原始树的情况下,将所有节点的关键字输出。
智谱清言:
在 Go 语言中,我们可以使用迭代的方式遍历二叉树,并输出每个节点的关键字。为此,我们可以使用一个长度为 n 的数组作为辅助空间,同时在遍历过程中,按照层序遍历的方式访问每个节点。以下是一个满足要求的 Go 代码实现:
package main
import "fmt"
type TreeNode struct {
Key int
Left *TreeNode
Right *TreeNode
}
func levelOrderTraversal(root *TreeNode, extraSpace int) {
if root == nil {
return
}
nodes := make([]*TreeNode, extraSpace)
nodes[0] = root
level := 1
for len(nodes) > 0 {
for i := 0; i < len(nodes); i++ {
node := nodes[i]
fmt.Print(node.Key, " ")
if node.Left != nil {
nodes = append(nodes, node.Left)
}
if node.Right != nil {
nodes = append(nodes, node.Right)
}
}
fmt.Println()
level++
for len(nodes) > 0 && level <= extraSpace {
nodes = nodes[1:]
level++
}
}
}
func main() {
root := &TreeNode{Key: 1}
root.Left = &TreeNode{Key: 2}
root.Right = &TreeNode{Key: 3}
root.Left.Left = &TreeNode{Key: 4}
root.Left.Right = &TreeNode{Key: 5}
root.Right.Right = &TreeNode{Key: 6}
levelOrderTraversal(root, 2)
}
在这个代码中,我们定义了一个TreeNode
结构体,用于表示二叉树的节点。levelOrderTraversal
函数接受一个二叉树的根节点和一个额外的存储空间大小作为参数。我们使用一个循环遍历二叉树,按照层序访问每个节点,并输出关键字。在每次循环中,我们使用辅助数组存储当前层的节点,并在访问完一层后移除该层节点。
注意,这个解决方案使用了额外的存储空间,但满足了题目要求的不修改二叉树的条件。
通义千问:
在 Go 语言中,可以使用广度优先搜索(BFS)来实现这个需求。广度优先搜索是一种图形遍历算法,它从根节点开始,首先访问与根节点相邻的所有节点,然后再依次访问这些节点的邻居。
以下是具体的代码实现:
package main
import (
"fmt"
)
type TreeNode struct {
Value int
Left *TreeNode
Right *TreeNode
}
func PrintTree(root *TreeNode) {
if root == nil {
return
}
queue := make([]*TreeNode, 0)
queue = append(queue, root)
for len(queue) > 0 {
node := queue[0]
fmt.Println(node.Value)
queue = queue[1:]
if node.Left != nil {
queue = append(queue, node.Left)
}
if node.Right != nil {
queue = append(queue, node.Right)
}
}
}
func main() {
root := &TreeNode{Value: 1}
root.Left = &TreeNode{Value: 2}
root.Right = &TreeNode{Value: 3}
root.Left.Left = &TreeNode{Value: 4}
root.Left.Right = &TreeNode{Value: 5}
root.Right.Left = &TreeNode{Value: 6}
root.Right.Right = &TreeNode{Value: 7}
PrintTree(root)
}
在这个代码中,我们使用了一个队列来存储待访问的节点。每次从队列的头部取出一个节点进行访问,并将其左右子节点加入到队列的尾部。这样就可以保证所有节点都会被访问到,并且只需要常数级别的额外空间。
天工:
以下是用Go语言实现的O(n)时间复杂度的非递归二叉树遍历过程,满足题目要求:
package main
import "fmt"
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func printInOrder(root *TreeNode) []int {
res := []int{}
cur := root
for cur != nil {
if cur.Left == nil {
res = append(res, cur.Val)
cur = cur.Right
} else {
printInOrder(cur.Left)
res = append(res, cur.Val)
cur = cur.Right
}
}
return res
}
func main() {
root := &TreeNode{1, &TreeNode{2, &TreeNode{4, nil, nil}, &TreeNode{5, nil, nil}}, &TreeNode{3, nil, nil}}
fmt.Println(printInOrder(root)) // Output: [1 2 4 5 3]
}
在这个实现中,我们使用了一个辅助函数printInOrder
,它使用一个res
切片来存储遍历结果,同时维护一个cur
指针来指向当前要访问的节点。在每次迭代中,我们首先检查cur
的左子节点是否为空,如果为空,说明cur
是一个叶节点,我们将cur
的值加入到res
中,并将cur
指向其右子节点。如果cur
的左子节点不为空,说明cur
有左子节点和右子节点,我们先递归访问其左子节点,直到找到叶节点,然后将cur
的值加入到res
中,并将cur
指向其右子节点。这样,我们就可以按照中序遍历的遍历顺序遍历整个树,并将每个节点的值保存到res
切片中,最后返回res
切片即可。
灵小智:
要实现非递归地遍历二叉树并输出每个节点的关键字,我们可以使用栈来模拟递归的过程。具体地,我们从根节点开始,将其入栈,然后遍历其左子树并将所有经过的节点入栈,直到遇到一个没有左孩子的节点。此时,我们弹出栈顶节点,输出其关键字,并遍历其右子树,将其右孩子以及其右孩子的左子树入栈。我们继续重复该过程,直到栈为空。由于每个节点最多入栈一次,出栈一次,因此时间复杂度为O(n),且空间复杂度为O(h),其中h为树的高度。
以下是用Go语言实现该算法的示例代码:
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func inorderTraversal(root *TreeNode) []int {
if root == nil {
return []int{}
}
var result []int
var stack []*TreeNode
for root != nil || len(stack) > 0 {
for root != nil {
stack = append(stack, root)
root = root.Left
}
root = stack[len(stack)-1]
stack = stack[:len(stack)-1]
result = append(result, root.Val)
root = root.Right
}
return result
}
该函数实现了二叉树的中序遍历,并返回每个节点的关键字。我们使用一个栈来保存经过的节点,在遍历当前节点的左子树时,将所有经过的节点入栈。当遇到一个没有左孩子的节点时,我们弹出栈顶节点并输出其关键字,并遍历以该节点为根的右子树,将其右孩子以及其右孩子的左子树入栈。重复该过程直到栈为空。
chatgpt:
下面是使用Go语言编写的非递归过程,按照中序遍历输出二叉树每个节点的关键字:
package main
import "fmt"
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func inorderTraversal(root *TreeNode) []int {
var result []int // 存储结果的数组
stack := []*TreeNode{} // 使用栈辅助进行迭代
current := root
for current != nil || len(stack) > 0 {
// 将左子树的所有节点入栈
for current != nil {
stack = append(stack, current)
current = current.Left
}
// 弹出栈顶元素并记录值
current = stack[len(stack)-1]
stack = stack[:len(stack)-1]
result = append(result, current.Val)
// 处理右子树
current = current.Right
}
return result
}
func main() {
// 构建示例二叉树: 1
// / \
// 2 3
// / \
// 4 5
root := &TreeNode{
Val: 1,
Left: &TreeNode{
Val: 2,
Left: &TreeNode{Val: 4},
Right: &TreeNode{Val: 5},
},
Right: &TreeNode{Val: 3},
}
result := inorderTraversal(root)
fmt.Println(result) // 输出 [4, 2, 5, 1, 3]
}
这里使用了栈来辅助进行迭代,通过模拟递归过程实现中序遍历。时间复杂度为 O(n),且只使用了固定量的额外存储空间(栈)。
文心一言 VS 讯飞星火 VS chatgpt (124)-- 算法导论10.5 5题的更多相关文章
- 【对比】文心一言对飚ChatGPT实操对比体验
前言 缘由 百度[文心一言]体验申请通过 本狗中午干饭时,天降短信,告知可以体验文心一言,苦等一个月的实操终于到来.心中这好奇的对比心理油然而生,到底是老美的[ChatGPT]厉害,还是咱度娘的[文心 ...
- 【个人首测】百度文心一言 VS ChatGPT GPT-4
昨天我写了一篇文章GPT-4牛是牛,但这几天先别急,文中我测试了用GPT-4回答ChatGPT 3.5 和 Notion AI的问题,大家期待的图片输入也没有出现. 昨天下午百度发布了文心一言,对标C ...
- 文心一言,通营销之学,成一家之言,百度人工智能AI大数据模型文心一言Python3.10接入
"文心"取自<文心雕龙>一书的开篇,作者刘勰在书中引述了一个古代典故:春秋时期,鲁国有一位名叫孔文子的大夫,他在学问上非常有造诣,但是他的儿子却不学无术,孔文子非常痛心 ...
- 获取了文心一言的内测及与其ChatGPT、GPT-4 对比结果
百度在3月16日召开了关于文心一言(知识增强大语言模型)的发布会,但是会上并没现场展示demo.如果要测试的文心一言 也要获取邀请码,才能进行测试的. 我这边通过预约得到了邀请码,大概是在3月17日晚 ...
- 百度生成式AI产品文心一言邀你体验AI创作新奇迹:百度CEO李彦宏详细透露三大产业将会带来机遇(文末附文心一言个人用户体验测试邀请码获取方法,亲测有效)
目录 中国版ChatGPT上线发布 强大中文理解能力 智能文学创作.商业文案创作 图片.视频智能生成 中国生成式AI三大产业机会 新型云计算公司 行业模型精调公司 应用服务提供商 总结 获取文心一言邀 ...
- 阿里版ChatGPT:通义千问pk文心一言
随着 ChatGPT 热潮卷起来,百度发布了文心一言.Google 发布了 Bard,「阿里云」官方终于也宣布了,旗下的 AI 大模型"通义千问"正式开启测试! 申请地址:http ...
- 基于讯飞语音API应用开发之——离线词典构建
最近实习在做一个跟语音相关的项目,就在度娘上搜索了很多关于语音的API,顺藤摸瓜找到了科大讯飞,虽然度娘自家也有语音识别.语义理解这块,但感觉应该不是很好用,毕竟之前用过百度地图的API,有问题也找不 ...
- android用讯飞实现TTS语音合成 实现中文版
Android系统从1.6版本开始就支持TTS(Text-To-Speech),即语音合成.但是android系统默认的TTS引擎:Pic TTS不支持中文.所以我们得安装自己的TTS引擎和语音包. ...
- android讯飞语音开发常遇到的问题
场景:android项目中共使用了3个语音组件:在线语音听写.离线语音合成.离线语音识别 11208:遇到这个错误,授权应用失败,先检查装机量(3台测试权限),以及appid的申请时间(35天期限), ...
- 初探机器学习之使用讯飞TTS服务实现在线语音合成
最近在调研使用各个云平台提供的AI服务,有个语音合成的需求因此就使用了一下科大讯飞的TTS服务,也用.NET Core写了一个小示例,下面就是这个小示例及其相关背景知识的介绍. 一.什么是语音合成(T ...
随机推荐
- 前端使用CSS固定表头
* { margin: 0; padding: 0 } .tableFixedTop { padding: 20px } .tableFixedTop table { border: 1px soli ...
- Codeforces Round #882 (Div. 2) A-D
比赛链接 A 代码 #include <bits/stdc++.h> using namespace std; using ll = long long; int a[107]; int ...
- IP 地址斜杠后的数字和子网掩码
目录 先上结论 IP 地址类型 ABC 类地址的划分 网络地址与广播地址 网络地址 广播地址 0.0.0.0 与 127.0.0.1 子网掩码 ABC 类 IP 地址最大网络范围与最大可用主机数 以 ...
- 用 perfcollect 洞察 Linux 上.NET程序 CPU爆高
一:背景 1. 讲故事 如果要分析 Linux上的 .NET程序 CPU 爆高,按以往的个性我肯定是抓个 dump 下来做事后分析,这种分析模式虽然不重但也不轻,还需要一定的底层知识,那有没有傻瓜式的 ...
- Python数据分析易错知识点归纳(二):Numpy
二.numpy 不带括号的基本属性 arr.dtype arr.shape # 返回元组 arr.size arr.ndim # 维度 arr.reshape/arr.resize/np.resize ...
- 2021-7-9 VUE的number\trim\lazy
Vue的v-model.number顾名思义,即是将绑定的参数中的字符串强制转换为int类型 而v-model.trim是将参数的前后空格删除 v-model.lazy:v-model的绑定是实时响应 ...
- Java8 函数式编程stream流
1.初始环境准备 场景:现在有一个公司,公司部门有一级部门,二级部门甲和二级部门乙(其中二级部门甲和二级部门乙是一级部门的子部门), 一级部门下面有有001号员工小明,二级部门甲下面有002号员工 ...
- Mysql 统计标签出现次数(一行变多行)
需求背景 需求 一张数据表 其中有sid字段,代表tag,每行数据可能有多个tag字段 统计全量数据中所有tag出现的次数(按tag分组,分别有多少数据) source table demo id s ...
- 解读 --- System.Windows.Forms.Timer是前台线程吗?
引言 今天同事问了我一个问题,System.Windows.Forms.Timer是前台线程还是后台线程,我当时想的是它是跟着UI线程一起结束的,应该是前台线程吧? 我确实没有仔细研究过他们的异同,所 ...
- 让C#调用vue组件里的方法
前言:web页面开发时采用的是vue开发的,后台语言是C# 需求:后台需要通过浏览器调用vue组件的方法 c# 可以调用xxx.html 中的script引用的js中定义的方法是可以调用的, 之前c# ...