【PAT】A1097 Depulication On a Linked List

Given a singly linked list L with integer keys, you are supposed to remove the nodes with duplicated absolute values of the keys. That is, for each value K, only the first node of which the value or absolute value of its key equals K will be kept. At the mean time, all the removed nodes must be kept in a separate list. For example, given L being 21→-15→-15→-7→15, you must output 21→-15→-7, and the removed list -15→15.

Input Specification:

Each input file contains one test case. For each case, the first line contains the address of the first node, and a positive N (≤10​5​​) which is the total number of nodes. The address of a node is a 5-digit nonnegative integer, and NULL is represented by −1.

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

Address Key Next

where Address is the position of the node, Key is an integer of which absolute value is no more than 10​4​​, and Next is the position of the next node.

Output Specification:

For each case, output the resulting linked list first, then the removed list. Each node occupies a line, and is printed in the same format as in the input.

Sample Input:

00100 5
99999 -7 87654
23854 -15 00000
87654 15 -1
00000 -15 99999
00100 21 23854

Sample Output:

00100 21 23854
23854 -15 99999
99999 -7 -1
00000 -15 87654
87654 15 -1

最后主要卡住的bug:

在next_index时,确实进行了处理,如果最后一个就是-1,正常的就用index。问题在于index可能为0,而之前只是使用%d,没有使用%5d(在-1时,又要使用%d)

说一下思路的变化:

1)将address和next_address 进行string2int的转换,存入map,这样根据address进行查找可以直接使用find,但是速度慢,并且空间会爆?

2)既然空间够用,那就开二维数组,使用二维数组,将地址存在数组里,速度快。这时,依然已经开了数组了,再使用string2int转换就没有必要了

另外就是如何将link分离

1)一开始时从start address进行遍历,遍历时,根据出现的顺序,依次递增,更新Num的id;然后根据id进行排序,即可得到原始的序列;

2)再得到序列之后,从前往后,一次判断是否相同,这个可以处理ABBBC,但是不能处理ABCBB的;

后来想到可以:

1)一开始时从start address进行遍历,遍历时,根据出现的顺序,依次递增,更新Num的id,这时,需要判断,并且根据bool类型的visit,判断是否出现过,如果出现过,则将id设置为INF+repeat_index;如果未出现过,则设置为unique_index;

2)注意,此时两个index是不一致的,分别用作重复的id和独一无二的id,并且将它们都压入一个数组中

3)使用sort排序,根据id大小进行区分,这样独一无二的就在前面,重复的就在后面。

并且此时已经根据unique_index知道了两部分的数量,控制好就可以输出。

这时,更简便的方法是,开两个vector,一个存unique,一个存重复,这样也不需要sort,也不需要id。

另外,在算法笔记中,不开vector,在一次遍历确定路径之后,根据id和各个部分的数量直接进行比较(三部分,重复,单一,不在链表内----不在链表内的id要在初始化时,设置为2*INF)。这样一次排完序后,控制好就可以输出了,省空间,费时间。

 

#include <iostream>
#include <map>
#include <string> 
#include <algorithm>
#include <vector> 
using namespace std;

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

const int INF = 100000;
struct Num{
	int number;
	int index;
	int next_index;
//	int id;
};

//bool cmp_id(Num &num_a, Num &num_b){
//	//if((num_a.number==num_b.number)||((num_a.number+num_b.number)==0)){
//	return(num_a.id<num_b.id);
//}

vector<Num> vec;
vector<Num> removed_vec;

Num node_map[INF];
bool node_visit[INF]={false};

int main(int argc, char** argv) {
	// disable sync of cin and cout
	ios::sync_with_stdio(false);
	int unique_index=0;
	int repeat_index=0;
	
	int start_num;
	int line_num,node_num;
	Num tmp_num;

	cin>>start_num>>line_num;
	
	node_num = line_num;
	
	while(line_num--){
		int cur_index,tmp_num,next_index,tmp_id;
		Num number_node;

		cin>>cur_index>>tmp_num>>next_index;
		
		//number_node.id = tmp_id;
		number_node.index  = cur_index;
		number_node.next_index = next_index;
		number_node.number = tmp_num;
		
		node_map[cur_index] = number_node;
	}

	// visit the node_map, and find the path
	int cur_index=start_num;
	while(cur_index!=-1){
		Num *node = &node_map[cur_index];
		if(node_visit[abs(node->number)] == false){
			node_visit [abs(node->number)]= true;
			//node->id = unique_index;
			unique_index++;
			vec.push_back(node_map[cur_index]);
		}else{
			//node->id = INF+repeat_index;
			repeat_index++;
			removed_vec.push_back(node_map[cur_index]);
		}
		cur_index= node->next_index;	
	}
		
	// now you get the list and sort them with id
	//sort(vec.begin(),vec.end(),cmp_id);
	
		
	for(int i=1;i<=vec.size();i++){
		int		index_pre 	= vec[i-1].index;
		int		num_pre  	= vec[i-1].number;
		int		index_post;
		if(i==vec.size()){
			index_post = -1;	
			printf("%05d %d %d\n",index_pre,num_pre,index_post);	
		}else{
			index_post = vec[i].index;		
			printf("%05d %d %05d\n",index_pre,num_pre,index_post);			
		}
		
	}

	for(int i=1;i<=removed_vec.size();i++){
		int		index_pre 	= removed_vec[i-1].index;
		int		num_pre  	= removed_vec[i-1].number;
		int		index_post;
		if(i==removed_vec.size()){
			index_post = -1;	
			printf("%05d %d %d\n",index_pre,num_pre,index_post);
		}else{
			index_post = removed_vec[i].index;
			printf("%05d %d %05d\n",index_pre,num_pre,index_post);		
		}
		
		
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值