Note:
Title:
Design the implementation of linked list. You can choose to use single linked list or double linked list. A node in a single linked list should have two attributes: val and next. val is the value of the current node, and next is the pointer / reference to the next node. If you want to use a two-way linked list, you also need an attribute prev to indicate the previous node in the linked list. It is assumed that all nodes in the linked list are 0-index.
Implement these functions in the linked list class:
get(index): Get the second in the linked list index The value of the first node. Returns if the index is invalid-1. addAtHead(val): Add a value before the first element of the linked list val Node for. After insertion, the new node will become the first node in the linked list. addAtTail(val): Set the value to val The node of is appended to the last element of the linked list. addAtIndex(index,val): The second in the linked list index Add value before nodes val Node for. If index Equal to the length of the linked list, the node will be attached to the end of the linked list. If index If it is greater than the length of the linked list, the node will not be inserted. If index Less than 0, the node is inserted in the head. deleteAtIndex(index): If index index If it is valid, the second item in the linked list will be deleted index Nodes.
Example:
MyLinkedList linkedList = new MyLinkedList();
linkedList.addAtHead(1);
linkedList.addAtTail(3);
linkedList.addAtIndex(1,2); // The linked list becomes 1 - > 2 - > 3
linkedList.get(1); // Return 2
linkedList.deleteAtIndex(1); // Now the linked list is 1 - > 3
linkedList.get(1); // Return 3
Tips:
All val values are within [1, 1000].
The number of operations will be within [1, 1000].
Do not use the built-in LinkedList library.
Solution:
A linked list is a data structure that contains zero or more elements. Each element contains a value and a link to another element. According to the number of links, it can be divided into single linked list, double linked list and multiple linked list.
Single linked list is the simplest one. It provides addAtHead operation in constant time and addAtTail operation in linear time. Double linked list is the most commonly used one, because it provides addAtHead and addAtTail operations in constant time, and optimizes insertion and deletion.
In a one-way linked list, we will use pseudo header nodes to simplify insertion and deletion.
In the bidirectional linked list, we will use pseudo head node and pseudo tail node to simplify insertion and deletion.
The following only shows the solution of the problem with one-way linked list:
Complexity analysis
Time complexity:
- addAtHead: O(1)
- addAtInder, get, deleteAtIndex: O(k), where k refers to the index of the element.
- addAtTail: O(N), where N refers to the number of elements in the linked list.
Spatial complexity: all operations are O(1).
class MyLinkedList { public: struct listnode{ int val; listnode* next; listnode(int _val):val(_val),next(nullptr){} }; /** Initialize your data structure here. */ MyLinkedList() { dummyhead=new listnode(-1); size=0; } /** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */ int get(int index) { if(index>=size||index<0){ return -1; } else{ listnode* node=dummyhead->next; while(index!=0){ node=node->next; index--; } return node->val; } return -1; } /** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */ void addAtHead(int val) { listnode* newhead=new listnode(val); newhead->next=dummyhead->next; dummyhead->next=newhead; size++; return ; } /** Append a node of value val to the last element of the linked list. */ void addAtTail(int val) { listnode* newnode= new listnode(val); listnode* cur=dummyhead; while(cur->next!=nullptr){ cur=cur->next; } cur->next=newnode; newnode->next=nullptr; size++; return ; } /** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */ void addAtIndex(int index, int val) { if(index<0){ this->addAtHead(val); } else if(index==size){ this->addAtTail(val); } else if(index>size){ return ; } else{ listnode* cur=dummyhead; listnode* newnode= new listnode(val); newnode->val=val; while(index!=0){ cur=cur->next; index--; } newnode->next=cur->next; cur->next=newnode; size++; } return ; } /** Delete the index-th node in the linked list, if the index is valid. */ void deleteAtIndex(int index) { if(index<0||index>=size){ return ; } else{ listnode* cur=dummyhead; while(index!=0){ cur=cur->next; index--; } listnode* temp=cur->next; cur->next=cur->next->next; delete temp; size--; } return ; } private: listnode* dummyhead; int size; }; /** * Your MyLinkedList object will be instantiated and called as such: * MyLinkedList* obj = new MyLinkedList(); * int param_1 = obj->get(index); * obj->addAtHead(val); * obj->addAtTail(val); * obj->addAtIndex(index,val); * obj->deleteAtIndex(index); */