Problem:
Doubly Linked List

Your task is to implement a double linked list.

Write a program which performs the following operations:

insert x: insert an element with key x into the front of the list.

delete x: delete the first element which has the key of x from the list. If there is not such element, you need not do anything.

deleteFirst: delete the first element from the list.

deleteLast: delete the last element from the list.

Input

The input is given in the following format:

n

command1

command2

...

commandn

In the first line, the number of operations n is given. In the following n lines, the above mentioned operations are given in the following format:

insert x

delete x

deleteFirst

deleteLast

Output

Print all the element (key) in the list after the given operations. Two consequtive keys should be separated by a single space.

Constraints

The number of operations ≤ 2,000,000

The number of delete operations ≤ 20

0 ≤ value of a key ≤ 109

The number of elements in the list does not exceed 106

For a delete, deleteFirst or deleteLast operation, there is at least one element in the list.

Sample Input 1

7
insert 5
insert 2
insert 3
insert 1
delete 3
insert 6
delete 5

Sample Output 1

6 1 2

Sample Input 2

9
insert 5
insert 2
insert 3
insert 1
delete 3
insert 6
delete 5
deleteFirst
deleteLast

Sample Output 2

1

Solution in C (judge verdict: Time Limit Exceeded)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
insert x: 連結リストの先頭にキー x を持つ要素を継ぎ足す
delete x: キー x を持つ最初の要素を連結リストから削除する
deleteFirst: リストの先頭の要素を削除する
deleteLast: リストの末尾の要素を削除する
*/

struct doubleList{
	
	struct doubleList *prev;
	int value;
	struct doubleList *next;
	
};
typedef struct doubleList DL;




void insert(int key);	//連結リストの先頭にキー x を持つ要素を継ぎ足す
void delete(int key);	//キー x を持つ最初の要素を連結リストから削除する
void deleteFirst(void);	//リストの先頭の要素を削除する
void deleteLast(void);	//リストの末尾の要素を削除する


void initialize(DL *p);
void displayAll(DL *p);


DL* gotoHead(DL *p);



DL *listHead;

int size;

int main(void)
{
	
	int n;
	int i;
	int key;
	
	size = 0;
	
	char order[100];
	char str[100];
	
	//まずリストヘッドの領域を取る。
	listHead = (DL*)malloc(sizeof(DL));
	
	//リストヘッドの初期化
	//initialize(listHead);
	listHead = NULL;
	
	
	//命令数nの入力
	fgets(order, sizeof(order), stdin);
	sscanf(order, "%d", &n);
	
	for(i=0; i<n; i++){
		
		//命令の入力
		fgets(order, sizeof(order), stdin);
		
		
		switch(strlen(order)){
			
			
			//deleteFirstの場合：
			case 12:
				deleteFirst();
				break;
				
			
			
			//deleteLastの場合：
			case 11:
				deleteLast();
				break;
				
			
			
			//それ以外の場合：
			default:
				sscanf(order, "%s %d\n", str, &key);
				
				//insertの場合
				if(strcmp(str, "insert") == 0){
					
					insert(key);
					
				}
				
				//deleteの場合
				else if(strcmp(str, "delete") == 0){
					
					delete(key);
					
				}
				
				//それ以外だった場合
				else{
					
					//printf("無効な入力です。\n");
					
				}
				
				break;
				
			
		}
		
		//displayAll(listHead);
		
	}
	
	displayAll(listHead);
	
	return 0;
	
}



void initialize(DL *p){
	
	p->prev = NULL;
	p->value = 0;
	p->next = NULL;
	
}



void displayAll(DL *p){
	
	if(p == NULL){
		
		return;
		
	}
	
	while(1){
		
		printf("%d", p->value);
		
		if(p->next == NULL){
			
			break;
			
		}
		else{
			
			printf(" ");
			
		}
		
		p = p->next;
		
	}
	
	printf("\n");
	
}



void insert(int key){
	
	DL *p = (DL*)malloc(sizeof(DL));
	p->prev = NULL;
	p->value = key;
	p->next = listHead;
	
	//リストヘッド（元）のprevに、今作ったポインタを繋げる
	if(size > 0){
		
		listHead->prev = p;
		
	}
	else{
		
		listHead = p;
		
	}
	
	//リストヘッドを更新する。
	listHead = p;
	
	size++;
	
}


void delete(int key){
	
	//リストヘッドからチェック開始
	DL *p;
	
	
	//最終的に削除できたかを管理
	int isDeleted = 0;
	
	while(1){
		
		
		//pの値がkeyと一致した場合：
		//if(p->value == key){
		if(listHead->value == key){
			
			//作業用の変数pにリストヘッドを移す
			p = listHead;
			
			//この時点でリストヘッドは先頭に戻る
			listHead = gotoHead(listHead);
			
			//1つ前の要素があるなら（＝最初の要素でなければ）、「1つ前の要素の、次の要素（＝今現在は自分が入っている）へのリンク」に、自分の次の要素を入れる（＝自分をスキップする形にする）
			if(p->prev != NULL){
				
				if(p->next != NULL){
					
					p->prev->next = p->next;
					
				}
				else{
					
					p->prev->next = NULL;
					
				}
				
			}
			
			//次の要素があるなら（＝最後の要素でなければ）、「1つ次の要素の、前の要素（＝今現在は自分が入っている）へのリンク」に、自分の前の要素を入れる（＝自分をスキップする形にする）」
			if(p->next != NULL){
				
				if(p->prev != NULL){
					
					p->next->prev = p->prev;
					
				}
				else{
					
					p->next->prev = NULL;
					
				}
				
			}
			
			//********************************************この時点で、1つ前からも1つ先からも、両方ともから自分はアクセスされない。	→	削除完了。******************************************
			
			//ついでにfreeでメモリ解放。
			free(p);
			
			//削除に成功した、という印。
			isDeleted = 1;
			
			//削除したらループを抜ける。s
			break;
			
		}
		
		
		//次の要素がもうない（＝最後の要素）の場合、ループを抜ける。
		//if(p->next == NULL){
		else if(listHead->next == NULL){
			
			break;
			
		}
		
		
		//現在地を1つ進める。
		//p = p->next;
		listHead = listHead->next;
		
	}
	
	
	//削除した場合とできなかった場合のメッセージ
	if(isDeleted){
		
		//printf("%d を削除しました\n\n", key);
		
	}
	else{
		
		//printf("%d は見つかりませんでした\n\n", key);
		
	}
	
	size--;
	
}


//リストの先頭の要素を削除する
void deleteFirst(void){
	
	//次の要素があったら、次の要素からの、自分へのリンクを切る。
	if(listHead->next != NULL){
		
		listHead->next->prev = NULL;
		
		//リストヘッドの更新
		listHead = listHead->next;
		
	}
	
	//次の要素がなかったら、自分をNULLにする。
	else{
		
		//
		listHead = NULL;
		
	}
	
	size--;
	
}



//リストの末尾の要素を削除する
void deleteLast(void){
	
	DL *p = listHead;
	
	while(p->next != NULL){
		
		p = p->next;
		
	}
	
	
	//printf("p->value = %d\n", p->value);
	
	
	//1つ前の要素があったら（＝要素が自分だけじゃなかったら）
	if(p->prev != NULL){
		
		//printf("p->prev->next->value = %d\n", p->prev->next->value);
		
		//1つ前の要素の、次の要素へのリンク（＝自分へのリンク）をNULLにする。（自分が最後の要素だから）
		p->prev->next = NULL;
		
		
		//printf("p->prev->next = %p\n", p->prev->next);
		
		//自分自身を消す。
		p = NULL;
		
	}
	else{
		
		p = NULL;
		
	}
	
	size--;
	
	//サイズが0になったら（＝要素が元々1つしかなく、それを今消したところだったら）、リストヘッドをNULLにする。
	if(size == 0){
		
		listHead = NULL;
		
	}
	
	
}



//リストの先頭まで戻る関数
DL* gotoHead(DL *p){
	
	while(p->prev != NULL){
		
		p = p->prev;
		
	}
	
	return p;
	
}