1032 Sharing (25 分)查找链表共同结点

版权声明:emmm……我也想成为大佬 https://blog.csdn.net/CV_Jason/article/details/84888491

题目

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 ( 1 0 5 ) 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

解题思路

  题目大意: 给定一堆字母,存储在链表的结点中,同时给定两个单词的开始地址,如果两个单词具有相同的后缀,那么链表将复用该后缀,请找出具有相同后缀的第一个结点的地址 。
  解题思路: 常规的做法是把输入的结点,按照地址进行构建单词链表,然后从后往前进行比较,得到最后一个不相同的点的地址即可 。但是这种方法要考虑边界情况,比如-1的处理,比如单词从一开头就是重复的等等。
  但这里可以用一种投机取巧的方法——从开始地址开始构建结点,如果结点在两个单词中均出现,那么必定会被访问两次,那么我们统计每个结点在构建的时候的访问次数,第一个超过1次的结点必定为相同后缀的开始结点,这样我们只需要从开始地址遍历链表即可,时间复杂度 O ( n ) O_(n) .
  但是值得一提的是,这种做法仅适用于测试数据里不存在2个以上的相同后缀的单词,不然的话,会干扰到正常判断。

/*
** @Brief:No.1032 of PAT advanced level.
** @Author:Jason.Lee
** @Date:2018-12-06 
** @status: Accepted!
*/
#include<iostream>
#include<vector>
#include<algorithm> 
using namespace std;

struct Node{
	int addr;
	int next;
	char key;
	int times;
};

Node input[100001];
// 从index开始构建单词链表
void createWordList(int index){
	while(index!=-1){
		input[index].times++;
		index = input[index].next;
	}
}

int main(){
	int index1,index2,N;
	while(scanf("%d%d%d",&index1,&index2,&N)!=EOF){
		Node temp{-1,-1,'\0',0};
		vector<Node> wordList1;
		vector<Node> wordList2;
		int commonNode = -1;
		int index = 0;
		bool always = true;
		fill(input,input+100001,temp);
		for(int i=0;i<N;i++){
			scanf("%d %c %d",&temp.addr,&temp.key,&temp.next);
			input[temp.addr] = temp;
		}
		if(index1!=-1&&index2!=-1){
			createWordList(index1);
			createWordList(index2);
			index = index1;
			while(index!=-1){//
				if(input[index].times>1){
					commonNode = input[index].addr;
					break;
				}
				index = input[index].next;
			}; 
		}
		commonNode==-1?printf("%d\n",commonNode):printf("%05d\n",commonNode);
	} 
	return 0;
}

在这里插入图片描述

总结

  第5个测试点输出的应该是个小于5位整型的数,忘记了printf("%05d",commonNode)这种做法,结果一直通不过,我以为时候我这种投机取巧的做法行不通,于是又老老实实写了一遍链表逆置,用的vector和reverse,结果多了一个第4个测试点超时了,不知道为啥会超时,可能是reverse的算法或者迭代器的方式,并没有那么高效吧。然后改用数组,自己写链表逆置,结果还是不行,最后不得不放弃,去网上找结题报告,发现有一个童鞋跟我的思路是一样的,为啥我不过呢?结果发现输出出了一点bug,吐血ing……

猜你喜欢

转载自blog.csdn.net/CV_Jason/article/details/84888491
今日推荐