【408算法】2012 两个单链表公共后缀的起始位置

193 阅读2分钟

题目

假定采用头结点的单链表保存单词, 当两个单词有相同的后缀时, 则可共享相同的后缀存储空间, 例如, 'loading'和'being'的存储映像如下图所示.

image.png 设 str1 和 str2 分别指向两个单词所在单链表的头结点, 链表结点结构为data-next, 请设计一个时间上尽可能高效的算法, 找出由 str1 和 str2 所指向两个链表共同后缀的起始位置 (如图中字符 i 所在的结点位置 p).

要求:

  1. 给出算法的基本设计思想

  2. 根据设计思想, 采用 C 或 C++ 或 Java 语言描述算法, 关键之处给出注释

  3. 说明你所设计算法的时间复杂度

暴力解

为考虑实际考场编写任何算法题时通用, 提供暴力解, 用于时间紧张, 没任何思路时的解法;

思路

双层循环获取str1和str2相同后缀的起始位置

时间复杂度:O(n2)O(n^2)

空间复杂度:O(1)O(1)

算法

#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;
    }
}