题目
假定采用头结点的单链表保存单词, 当两个单词有相同的后缀时, 则可共享相同的后缀存储空间, 例如, 'loading'和'being'的存储映像如下图所示.
设 str1 和 str2 分别指向两个单词所在单链表的头结点, 链表结点结构为
data-next, 请设计一个时间上尽可能高效的算法, 找出由 str1 和 str2 所指向两个链表共同后缀的起始位置 (如图中字符 i 所在的结点位置 p).
要求:
-
给出算法的基本设计思想
-
根据设计思想, 采用 C 或 C++ 或 Java 语言描述算法, 关键之处给出注释
-
说明你所设计算法的时间复杂度
暴力解
为考虑实际考场编写任何算法题时通用, 提供暴力解, 用于时间紧张, 没任何思路时的解法;
思路
双层循环获取str1和str2相同后缀的起始位置
时间复杂度:
空间复杂度:
算法
#include <cstdio>
#include <cstdlib>
#include <string.h>
typedef struct node
{
char data;
struct node *next;
} Node;
Node *find_end_same(Node *first_str, Node *secend_str)
{
if (first_str == nullptr) return nullptr;
if (secend_str == nullptr) return nullptr;
Node *p = first_str->next;
while (p != nullptr)
{ // 外层循环遍历str1
Node *q = secend_str->next;
while (q != nullptr)
{ // 内层循环遍历str2,地址相同表示开始点
if (p == q)
{
return p;
}
q = q->next;
}
p = p->next;
}
return nullptr;
}
//=================以下为测试========================
int main()
{
Node *first_str, *secend_str;
first_str = (Node *)malloc(sizeof(Node));
first_str->next = NULL;
secend_str = (Node *)malloc(sizeof(Node));
secend_str->next = NULL;
create(first_str, secend_str);
Node *s = find_end_same(first_str, secend_str);
printf("%c", s->data);
print(s);
return 0;
}
// 使用尾插法创建结点
void create(Node *&first, Node *&secend)
{
Node *r1 = first, *r2 = secend, *p;
int num;
char word1[] = "loading";
char word2[] = "being";
// 数据1
for (int i = 0; i < strlen(word1); i++)
{
Node *s = (Node *)malloc(sizeof(Node));
s->data = *(word1 + i);
r1->next = s;
r1 = s;
}
r1->next = NULL;
p = first;
while (p->next != NULL)
{
p = p->next;
if (p->data == 'i')
break;
}
// 数据2
for (int i = 0; i < sizeof(word2) - 1; i++)
{
Node *s = (Node *)malloc(sizeof(Node));
// 对指针 word2 进行偏移 i 个位置后取值
s->data = *(word2 + i);
if (s->data == 'i')
{
r2->next = p;
break;
}
r2->next = s;
r2 = s;
}
}
// 打印数据
void print(Node *L)
{
Node *p = L;
while (p != NULL)
{
printf("%c", p->data);
p = p->next;
}
}