【408DS算法题】024进阶-12年真题_找出两个链表的共同后缀的起始位置

真题题目

假定采用带头结点的单链表保存单词,当两个单词有相同的后缀时,则可共享相同的后缀存储空间,例如,“loading”和“being”的存储映像如下图所示。
在这里插入图片描述
str1str2分别指向两个单词所在单链表的头结点,链表结点结构为{[data][next]},请设计一个时间上尽可能高效的算法,找出由str1str2所指向两个链表共同后缀的起始位置(如图中字符i所在结点的位置p)。要求:

  1. 给出算法的基本设计思想。
  2. 根据设计思想,采用C或 C++语言描述算法,关键之处给出注释。
  3. 说明你所设计算法的时间复杂度。

(本文重点关注算法实现及思路分析,不含具体答题表述)

分析实现

和判断子串的算法不同,本题中明确是检查相同的后缀。因此,一个简单的思路是将两个单词逆置,然后逐步比较到不同的结点即可。

但以上思路会破坏两单词链表的结构,若要实现则需要新建链表进行模拟,再记录下共同后缀的起始位置完成搜索。虽然可以在 O ( n ) O(n) O(n)的时间复杂度下完成,但还是相对繁琐的。

至于优化的思路,可以“反过来想”——将较长的单词多出来的字母“舍去”,这样两单词从头开始扫描,遇到的第一个共同结点就是目标结点。
具体在代码中可以使用双指针来实现这一思路,具体实现如下:

// 定义链表结点结构体
struct LNode{
    char data;
    LNode *next;
};
// 辅助函数,计算链表的长度
int getLength(LNode *head){
    int len=0;
    while(head){
        len++;
        head=head->next;
    }
    return len;
}

// 查找第一个相同结点
LNode* findFirstCom(LNode *str1, LNode *str2){
    int m = getLength(str1);
    int n = getLength(str2);
    // cur1和cur2分别指向两单词中要匹配的字母
    LNode *cur1=str1, *cur2=str2;
    // “舍去”单词1中的字母
    while(m>n){
    	m--;
    	cur1=cur1->next;
    }
    // “舍去”单词2中的字母
    while(m<n){
    	n--;
    	cur2=cur2->next;
    }
    // 扫描第一个相同结点
    while(cur1!=cur2){
        cur1=cur1->next;
        cur2=cur2->next;
    }
    return cur1;
}

总结

以上就是运用双指针找出两链表共同后缀起始位置的实现,思路相对比较新颖,但操作并不复杂。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值