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

怎么给自己建网站大同网站建设开发

怎么给自己建网站,大同网站建设开发,百度推广一级代理商名单,wordpress商业用途本篇文章将为大家讲解一道关于链表的经典题目——求两个链表的共同后缀节点。该问题在实际开发中同样具有很大的应用价值#xff0c;是每一位数据结构学习者不可错过的重要题目。 问题描述 假设我们有一个带头结点的单链表来保存单词#xff0c;每个节点包含一个字符和指向…本篇文章将为大家讲解一道关于链表的经典题目——求两个链表的共同后缀节点。该问题在实际开发中同样具有很大的应用价值是每一位数据结构学习者不可错过的重要题目。 问题描述 假设我们有一个带头结点的单链表来保存单词每个节点包含一个字符和指向下一个节点的指针。若两个单词的后缀相同它们可以共享相同的后缀存储空间。例如 单词loading 和 being 有相同的后缀 ing可以共享存储。 题目要求 设 str1 和 str2 分别指向两个单词所在链表的头节点请设计一个尽可能高效的算法找出两个链表共同后缀的起始位置。 要求 给出算法的设计思想。使用 C 代码实现算法并在关键部分给出注释。分析算法的时间复杂度。 设计思路 1. 暴力匹配法 最直接的思路是将链表 str1 的每一个节点依次与链表 str2 的节点进行匹配如果匹配到相同的节点则继续向后比较直到找到第一个完全相同的后缀位置。 实现步骤 从链表 str1 开始的每个节点分别与 str2 中的节点开始逐一匹配。若匹配的节点数据相同继续匹配下一个节点若不相同则跳到下一个节点。当匹配到第一个后缀起始点时返回该节点位置。 #include bits/stdc.husing namespace std;struct Node{int value;Node* next; };bool check(Node* first, Node* second) {Node* l first;Node* r second;while(l ! nullptr r ! nullptr) {if(l - value ! r -value) return false;l l - next;r r - next;}return l nullptr r nullptr; }Node* search(Node* first, Node* second) {Node* x first;while(x ! nullptr ) {Node* y second;while(y ! nullptr) {if(x - value y - value check(x, y)) {return x;}y y - next;}x x - next;}return nullptr; }int main() {Node* common new Node{i, new Node{n, new Node{g, nullptr}}};// 创建两个测试链表Node* str1 new Node{ l, nullptr };str1-next new Node{ o, nullptr };str1-next-next new Node{ a, nullptr };str1-next-next-next new Node{ d, nullptr };str1-next-next-next-next common;Node* str2 new Node{ b, nullptr };str2-next new Node{ e, nullptr };str2-next-next common; // 共享后缀部分// 查找共同后缀的起始位置Node* result search(str1, str2);if (result ! nullptr) {cout 共同后缀的起始位置: (char)result-value endl;} else {cout 没有共同后缀 endl;}return 0; }代码结构分析 search 函数这是主函数它通过双层循环在链表 first 和 second 中查找共同后缀的起始位置。 外层循环遍历链表 first 的每个节点 x。内层循环对于每个节点 x遍历链表 second 的每个节点 y。 check 函数search 函数在 if(x - value y - value check(x, y)) 中调用 check 函数用于比较链表 first 从节点 x 开始的后缀和链表 second 从节点 y 开始的后缀。 check 函数的时间复杂度为 (O(n))因为它从两个节点开始逐一比较剩下的所有节点。 时间复杂度计算 外层循环遍历链表 first 的每个节点时间复杂度为 (O(m))m 是链表 first 的长度。内层循环遍历链表 second 的每个节点时间复杂度为 (O(n))n 是链表 second 的长度。check 函数的复杂度为 (O(k))其中 k 是 x 和 y 之后的节点数量最多接近 O(max(m, n))。 因此整体时间复杂度为 O ( m × n × k ) ≈ O ( n 3 ) O(m \times n \times k) \approx O(n^3) O(m×n×k)≈O(n3) 2. 双指针法 考虑一种更为高效的 双指针法。 思路 我们先遍历两个链表得到它们的长度差 d。然后让较长的链表先走 d 步这样两个链表剩下的节点数相等。之后同时遍历两个链表直到找到第一个相同的节点即为共同后缀的起始位置。 实现步骤 计算两个链表的长度 len1 和 len2求得它们的长度差 d。将较长的链表向前移动 d 步。同时遍历两个链表直到找到第一个相同的节点。 优点通过两次遍历计算长度 查找共同节点时间复杂度降低到 O(m n)。 C 实现代码 以下是使用 C 实现的双指针法代码 #include bits/stdc.h using namespace std;struct Node{int value;Node* next; }; // 计算链表长度 int getLength(Node* node) {int length 0;while(node ! nullptr) {length;node node - next;}return length; }// 查找共同后缀起始节点 Node* search(Node* n, Node* m) {int len1 getLength(n);int len2 getLength(m);// 长链表先走 |len1 - len2| 步while(len1 len2) {len1--;n n - next;}while(len2 len1) {len2--;m m - next;}// 双指针同时遍历寻找共同节点while(n ! nullptr m ! nullptr) {if(n m ) return n;n n - next;m m - next;}return nullptr; }int main() {Node* common new Node{i, new Node{n, new Node{g, nullptr}}};Node* str1 new Node{ l, nullptr };str1-next new Node{ o, nullptr };str1-next-next new Node{ a, nullptr };str1-next-next-next new Node{ d, nullptr };str1-next-next-next-next common;Node* str2 new Node{ b, nullptr };str2-next new Node{ e, nullptr };str2-next-next common;Node* result search(str1, str2);if (result ! nullptr) {cout 共同后缀的起始位置: (char)result-value endl;} else {cout 没有共同后缀 endl;}return 0; }这段代码的核心思想是通过调整两个链表的起始位置使得它们在同一个位置开始比较以便找到第一个相同的节点作为共同后缀的起始点。以下是逐步的代码讲解特别是对为什么较长的链表需要先移动几步的解释。 代码分解与讲解 #include bits/stdc.h using namespace std;struct Node{int value;Node* next; }; 这里定义了链表节点的结构体 Node包含一个整型数据 value 和一个指向下一个节点的指针 next。 int getLength(Node* node) {int length 0;while(node ! nullptr) {length;node node - next;}return length; }getLength 函数用于计算链表的长度。它遍历链表并计数直到链表末尾。时间复杂度为 (O(n))其中 (n) 是链表的长度。 Node* search(Node* n, Node* m) {int x getLength(n);int y getLength(m);search 函数是主函数用来找到两个链表的共同后缀。首先调用 getLength 获取链表 n 和 m 的长度分别记为 x 和 y。 为什么较长的链表要先移动 假设链表 n 比链表 m 长。如果直接从头开始同时遍历两个链表由于长度不相等较长链表的指针会先到达结尾而我们需要两个链表在“对齐的起始位置”进行比较。 因此为了让两个链表末尾部分对齐 让较长的链表先移动 |x - y| 步。这样移动后两个链表的剩余部分长度相等。从这个新位置开始两个链表的指针将同步向后遍历确保同时到达链表的末尾。 while(x y) {x--;n n - next;} while(y x) {y--;m m - next;}在这里较长的链表会先移动 |x - y| 步以确保后续同步遍历时两链表末尾部分的节点数相同。 while(n ! nullptr m ! nullptr) {if(n m) return n;n n - next;m m - next;}return nullptr; }现在两个链表 n 和 m 同时从新的位置开始遍历。如果发现 n 和 m 指向同一个节点即它们有相同的地址则该节点即为第一个公共节点返回该节点。如果遍历结束未找到公共节点则返回 nullptr表示没有共同后缀。 算法时间复杂度分析 计算长度 函数 getLength 分别计算链表 n 和 m 的长度耗时为 (O(m)) 和 (O(n))。 对齐链表长度 假设 str1 比 str2 长。为了让两个链表的尾端对齐较长的链表 str1 向前移动 |m - n| 步。无论如何对齐过程的时间复杂度是 (O(|m - n|))这可以简化为 (O(m n))。 寻找共同后缀 接下来两个链表同时从对齐位置向后遍历寻找第一个相同的节点。这部分的时间复杂度为 O ( m i n ( m , n ) ) O(min(m, n)) O(min(m,n))但可以包含在 O ( m i n ( m , n ) ) O(min(m, n)) O(min(m,n))的上界内。 因此整个算法的时间复杂度为 O ( m i n ( m , n ) ) O(min(m, n)) O(min(m,n))这涵盖了所有操作的最坏情况时间复杂度。这种算法之所以更高效是因为它只需要遍历每个链表最多两次。 结语 双指针法通过巧妙地同步遍历来提高效率非常适合此类链表问题。在链表题目中理解如何通过双指针控制遍历过程可以显著提升算法的效率。希望这篇文章能够帮助大家更好地理解链表的双指针技巧。
http://www.ho-use.cn/article/10817262.html

相关文章:

  • 公众号里链接的网站怎么做的wordpress 自定义链接
  • 网站网页的像素尺python做网站多么
  • 找公司做网站有什么好处图片外链生成器
  • 视频logo免费生成网站软件山东兴华建设集团网站
  • 博罗做网站报价怎么投放网络广告
  • 网站推广的方法有sem推广淘宝网站建设的详细策划
  • 遵义市建设厅网站免费软件下载网站入口正能量
  • 想做一个自己的网站怎么做的网站推广软件免费下载安装
  • 网站开发免责合同品牌线上营销策划
  • scratch少儿编程软件下载湖南sem优化
  • 马鞍山网站开发流程中国互联网网站性能
  • 商城网站开发教程视频宿州网站建设哪家好
  • 网站手机站怎么做的京东商城网页设计分析
  • 网站建设费要交印花税吗学校网页网站模板免费下载
  • 长春网站关键词排名企业网站建设的一般要素主要包括网站的
  • 邯郸企业网站建设价格装修设计图网站排名
  • 做游戏网站定位杭州网站推广怎样做
  • 网站优化方案书用discuz可以做视频网站吗
  • apmserv访问本地网站网上怎么自己审核营业执照
  • 服装网站建设策划书简易制作网站
  • 大数据统计网站郑州哪里做网站汉狮
  • 免费下载ppt模板网站哪个好网站建设一般用什么语言好
  • 公司网站制作专业公司企业信用公示信息网
  • 泉州百度搜索推广系统清理优化工具
  • 江西省上饶市网站建设公司wordpress 首页显示分类文章
  • 英国做电商网站手机版网页开发
  • 免费申请网站官网企业推广托管
  • 长沙河东做网站小城镇建设的网站中的主要观点
  • 网站推广渠道咨询中核二二正式员工一月多少钱
  • 李贤威wordpress建站教程手机网站模板 源码