A1032 Sharing (25)

1. 描述

To store English words, one method is to use linked lists and store a word letter by letter. To save some space, we may let the words share the same sublist if they share the same suffix. For example, loading and being are stored as showed in Figure 1.

Figure 1

You are supposed to find the starting position of the common suffix (e.g. the position of i in Figure 1).

Input Specification:

Each input file contains one test case. For each case, the first line contains two addresses of nodes and a positive N (<=10^5), where the two addresses are the addresses of the first nodes of the two words, and N is the total number of nodes. The address of a node is a 5-digit positive integer, and NULL is represented by −1.

Then N lines follow, each describes a node in the format:

Address Data Next

whereAddress is the position of the node, Data is the letter contained by this node which is an English letter chosen from { a-z, A-Z }, and Next is the position of the next node.

Output Specification:

For each case, simply output the 5-digit starting position of the common suffix. If the two words have no common suffix, output -1 instead.

Sample Input 1:

11111 22222 9
67890 i 00002
00010 a 12345
00003 g -1
12345 D 67890
00002 n 00003
22222 B 23456
11111 L 00001
23456 e 67890
00001 o 00010

Sample Output 1:

67890

Sample Input 2:

00001 00002 4
00001 a 10001
10001 s -1
00002 a 10002
10002 t -1

Sample Output 2:

-1

2. 解题思路

        本题的背景是408真题中的一道编程题目

  • 输入的数据结构是静态链表,我们可以将其使用静态链表存储(两个数组or一个结构体),过滤无效节点后,然后可以转为数组存储,方便后续操作
  • 要想找到相同的节点,设置两个指针,i,j,i指向一个串,j指向一个串,然后同时向后移动,当较短的串指针到达尾部时,较长的串指针正好指向共同子串开始节点(因为串长度的差正好是共同子串的长度)

3. Code

      代码流程

  1. 用结构体数组存储静态链表,排序结构体数组并去除无效节点
  2. 用i和j分别从start1,start2开始往后遍历,找到共同子串节点开始的位置
#include <iostream>
#include <vector>
#include<algorithm>
#include <iterator>
using namespace std;
struct node{
    int addr;
    char c;
    int next;
}List[100005];
int main()
{
    int start1,start2,N;
    int commonNode;
    scanf("%d %d %d",&start1,&start2,&N);
// 用结构体存储静态链表
    node temp;
    for(int i=0;i<N;i++)
    {
        scanf("%d %c %d",&temp.addr,&temp.c,&temp.next);
        List[temp.addr] = temp;
    }
//  i,j同步往后遍历
    int i=start1,j=start2;
    while(List[i].next!=-1 && List[j].next!=-1)
    {
        i = List[i].next;
        j = List[j].next;

    }
//   有一个链子到-1了
    if(List[i].next==-1)// i串到-1
    {
        commonNode = List[j].addr;

    } else{
        commonNode = List[i].addr;

    }
    if(List[i].next==-1&&List[j].next==-1)
    {
        commonNode = -1;

    }
    if(commonNode ==-1)
    {
        printf("%d\n",commonNode);
    } else{
        printf("%05d\n",commonNode);
    }

    return 0;
}

4. 遇到的问题

  1. 一顿操作猛如虎,定睛一看测试用例还有三个过不了,应当是思考不周了,让我再思考思考
  2. 实在想不通,也没有找到类似的做法的


以下是目前能够AC的解法

1. 思路

  • 在每个节点上设置一个flag标志,首先遍历一条链,然后设置flag为true
  • 再从另外一条链进行遍历,对于flag为false的节点设置为true,对于已经为true的节点,表示这个结点是公共节点的第一个

2. Code

       代码流程

  1. 用结构体存储静态链表
  2. 遍历第一条链
  3. 遍历并检查第二条链
#include <iostream>
#include <vector>
#include<algorithm>
#include <iterator>
using namespace std;
struct node{
    int addr;
    bool flag;
    int next;
}List[100005];
int main()
{
    int start1,start2,N;
    int commonNode=-1;
    scanf("%d %d %d",&start1,&start2,&N);
// 用结构体存储静态链表
    node temp;
    for(int i=0;i<N;i++)
    {
        char c;
        temp.flag = false;
        scanf("%d %c %d",&temp.addr ,&c,&temp.next);
        List[temp.addr] = temp;
    }
// 遍历第一条链
//for(int p=start1;p!=-1;p = List[p].next)
//{
//    List[p].flag = true;
//}
   while(start1!=-1)
   {
       List[start1].flag = true;
       start1 = List[start1].next;
   }
// 遍历第二条链
//    for(int p=start2;p!=-1;p = List[p].next)
//    {
//        if(List[p].flag== true)
//        {
//            commonNode = p;
//            break;
//        }
//
//    }
    while(start2!=-1)
    {
        if(List[start2].flag== true) {
            commonNode = List[start2].addr;
            break;
        }

        start2 = List[start2].next;
    }
    if(commonNode==-1)
    {
        printf("-1\n");
    } else{
        printf("%05d\n",commonNode);
    }

    return 0;
}

3. 问题 (遍历边界)

这段代码是有问题的,当我们到最后一个节点的时候,不能进入while循环内的

   while(List[start1].next!=-1)
   {
       List[start1].flag = true;
       start1 = List[start1].next;
   }

应当使用下面一段代码,去判断地址是否是-1

while(start1!=-1)
   {
       List[start1].flag = true;
       start1 = List[start1].next;
   }

4. 思考与收获

  • 静态链表用结构体数组存储是需要条件的(地址是整数,不太大)
  • 注意边界条件

猜你喜欢

转载自blog.csdn.net/weixin_45621688/article/details/130401398
今日推荐