当前位置: 首页 > news >正文

C++系列之刷题系列(树)


前言

本次数据结构课也是不出我所料留的题有点难度。这两道题都可以加深对树的理解和操作。


一、根据后序中序确定前序

首先我们要明白,二叉树中根据前序和中序 或者 中序和后序也就是说-----中序和另外一个序列就可以确定树的结构-----为什么????无论是前序还是后序都能确定根的位置,中序通过确定根分为左右子树,递归下去即可得到树的结构。

1.根据两种遍历顺序确定一棵树的结构。给出一棵二叉树的中序与后序排列。求出它的先序排列。(约定树结点用不同的大写字母表示,长度≤8)。

输入格式:第一行为二叉树的中序序列,第二行为二叉树的后序序列
输出格式:一行,为二叉树的先序序列

样例输入:
BADC
BDCA
样例输出:
ABCD
思路:递归 后序是左右根,因此后序的最后一个元素一定是根节点
而中序是左根右,找到了根的位置就可以递归去连接左子树和右子树
比如:中序:BADC 后序:BDCA
找到这个A说明为根节点,找到A在中序的位置,B就是A的左子树,DC就属于A的右子树,递归下去,后序的倒数第二个下标是C,找到C在中序的位置,递归下去…
由于需要快速获取某个字符在中序中的位置,需要我们维护一个哈希表,即元素和下标的位置即可。

#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
struct Node{char val;Node* left,*right;Node(int v):val(v),left(nullptr),right(nullptr){}
};
string str1,str2;
unordered_map<char,int> mp;
int pos; //维护下标,初始化是str2.size() - 1,也就是维护根节点下标
Node* CreateTree(int left,int right)
{if(left > right) return nullptr;char rootval = str2[pos];Node* newnode = new Node(rootval);int idx = mp[rootval]; //找寻根节点在中序中的位置pos--;newnode->right = CreateTree(idx + 1,right);newnode->left = CreateTree(left,idx - 1);return newnode;
}void PrevOrder(Node* node)
{if(node == nullptr) return;cout << node->val;PrevOrder(node->left);PrevOrder(node->right);
}
int main()
{getline(cin,str1);getline(cin,str2);//输入中序和后序序列int idx = 0;for(char e:str1)  mp[e] = idx++;pos = str2.size() - 1;Node* root = CreateTree(0,str2.size() - 1);PrevOrder(root);return 0;
}

二、lca问题(公共祖先问题)

给定一棵树,同时给出树中的两个结点(n1和n2),求它们的最近公共祖先。
这里给出三种思路

1.找路径

思路:
(1)找到从根到n1的路径,并存储在栈中
(2)找到从根到n2的路径,并存储在另一个栈中
(3)这两个栈存着他们倒着的路径,先让size大的pop到和另一个size一样,同时pop,相等就是lca
这个过程很好想比如一个是9 4 5 1,另一个是9 4,出掉5 1,4就是lca
问题是怎么找到路径,这里用栈比较合适,发现这个节点不符合要求就pop掉,进来的节点先push

    bool Find(TreeNode*node,TreeNode* find,stack<TreeNode*>& st){if(node == nullptr) return false;st.push(node);if(find == node) return true;if(Find(node->left,find,st)) return true;if(Find(node->right,find,st)) return true;st.pop();return false;}TreeNode* GetLca(TreeNode* root, TreeNode* p, TreeNode* q)  {stack<TreeNode*> stp,stq;Find(root,p,stp);Find(root,q,stq);if(stp.size() < stq.size()) stp.swap(stq);//3 5   3 1 while(stp.size() != stq.size()) stp.pop();while(stp.top() != stq.top()){stp.pop(),stq.pop();}return stp.top();}

时间复杂度:O(N)

2.递归

可能不太好想,结合注释来看还是可以理解的。

TreeNode *GetLca(TreeNode *root, TreeNode *p, TreeNode *q)
{if (!root || root == p || root == q) return root;//左子树找p或者qTreeNode *left = GetLca(root->left, p, q);//右子树找p或者qTreeNode *right = GetLca(root->right, p, q);//如果都找到了,说明根就是lcaif (left && right) return root;//没找到,返回上一层return left ? left : right;
}

时间复杂度:O(N)


3.倍增求LCA

这个做法是比较多的做法,因为构建完成之后每次查询的时间复杂度都是logN
板子:

//第二种思路:倍增求lca,构建完是nlogN,之后每次查询都是logN
const int mod = 1e9 + 7;
const int N = 1e5 + 1;
vector<int> g[N];
int fa[N][24],dep[N];
int lca(int x,int y)
{if(dep[x] < dep[y]) swap(x,y);for(int i = 20;i >= 0;i --){if(dep[fa[x][i]] >= dep[y]) x = fa[x][i];}if(x == y) return x;for(int i = 20;i >= 0;--i) if(fa[x][i] != fa[y][i]) x = fa[x][i],y = fa[y][i];return fa[x][0];
}
void dfs(int x,int f)
{dep[x] = dep[f] + 1;fa[x][0] = f;for(int i = 1;i <= 20;i++) fa[x][i] = fa[fa[x][i - 1]][i - 1];for(const auto& y:g[x]){if(y == f)continue;dfs(y,x);}
}void solve()
{int n;cin >> n;while(--n){int x,y;cin >> x >> y;g[x].push_back(y),g[y].push_back(x);}int m;cin >> m;dfs(1,1);while(m--){int x,y;cin >> x >> y;cout << lca(x,y) << endl;}
}

OiWiki
OiWiki里面给的比较详细,也有思路,想看可以看一看。
时间复杂度:O(NlogN + MlogN) M代表查询的次数,N是节点个数。

http://www.dtcms.com/a/601496.html

相关文章:

  • 07-ES分布式搜索引擎高级
  • NVIDIA Orin NX使用Jetpack安装CUDA、cuDNN、TensorRT、VPI时的error及解决方法
  • 青岐网站建设平台大气物流网站模块
  • 南昌营销网站公司全球优秀企业网站
  • 数据分析笔记03:概率分布理论
  • SpringCloud零基础学全栈,实战企业级项目完整使用
  • 扁平化设计网站欣赏网站做
  • 【开题答辩过程】以《基于SpringBoot+VUE的商场人流监控及分析系统的设计与实现》为例,不会开题答辩的可以进来看看
  • 网站登录不了哪里网站用vue.js做的
  • 网站备案审核通过时间品牌搜索
  • 孤能子视角:数字社会治理框架
  • C Primer Plus Notes 11
  • LangChain v1.0学习笔记(1)
  • [Linux]学习笔记系列 -- [kernel]ksysfs
  • 庆阳市建设局网站怎么设置iis默认网站
  • 前端安全展示后端纯文本接口数据的实践:不解析、不危险渲染的结构化方案
  • 【2024年莆田市校园创客节(小学组)初赛】泡泡堂
  • 河南省网站建设电脑网页
  • Doc-Researcher: 多模态文档深度研究系统的技术解析
  • E3Docker,一键解锁E3连接酶配体发现新纪元!
  • 【AI智能体】Coze 基于关键词生成古诗词 + 配图智能体操作详解
  • 百日挑战——单词篇(第二十天)
  • Vue 3组合式API中ref与reactive的核心响应式差异及使用最佳实践是什么?
  • 创意网站推荐智能手机网站模板
  • JAVA学习笔记——集合的概念和习题
  • 商城网站开发方案书导购类网站备案
  • leetcode 290. 单词规律 python
  • D037 vue+django三国演义知识图谱可视化系统
  • 连接一个新的服务器时,打开PyCharm时报错:报错内容是服务器磁盘或配额满了
  • 传媒有限公司免费网站武安市精品网站开发