get(index): Get the value of theindex-th node in the linked list. If the index is invalid, return -1.addAtHead(val): Add a node of valuevalbefore the first element of the linked list. After the insertion, the new node will be the first node of the linked list.addAtTail(val): Append a node of valuevalas the last element of the linked list.addAtIndex(index, val): Add a node of valuevalbefore theindex-th node in the linked list. Ifindexequals the length of the linked list, the node will be appended to the end. If the index is greater than the length, the node will not be inserted. If index is less then 0, insert the node at the head.deleteAtIndex(index): Delete theindex-th node in the linked list, if the index is valid.
LeetCode Problem 707: Design Linked List
class MyLinkedList {
public:
// Define the structure of a linked list node
struct Node {
int val;
Node* next;
Node(int val) : val(val), next(nullptr) {} // Constructor using initializer list
};
// Initialize the linked list
MyLinkedList() {
dummyHead = new Node(0); // A dummy head node, not an actual real head
size = 0;
}
// Get the value of the index-th node. If index is invalid, return -1.
// Index starts from 0. The 0-th node is the first actual node.
int get(int index) {
if (index > (size - 1) || index < 0) {
return -1;
}
Node* cur = dummyHead->next; // Start from the first real node
while (index--) { // Move index times
cur = cur->next;
}
return cur->val;
}
// Add a node at the head: new node becomes the first real node.
void addAtHead(int val) {
Node* newNode = new Node(val);
newNode->next = dummyHead->next; // Link original first node to new node's next
dummyHead->next = newNode; // Dummy head's next points to new node
size++;
}
// Add a node at the tail
void addAtTail(int val) {
Node* newNode = new Node(val);
Node* cur = dummyHead; // Start from dummy head (in case list is empty)
while (cur->next != nullptr) {
cur = cur->next;
}
cur->next = newNode;
size++;
}
// Add a node before the index-th node.
// If index equals the length, add at the tail.
// If index > length, do nothing.
// If index < 0, insert at head (treated as 0).
void addAtIndex(int index, int val) {
if (index > size) return;
if (index < 0) index = 0;
Node* newNode = new Node(val);
Node* cur = dummyHead;
while (index--) {
cur = cur->next;
}
// Insert newNode between cur and cur->next
newNode->next = cur->next;
cur->next = newNode;
size++;
}
// Delete the index-th node (0-indexed). If index is invalid, return.
void deleteAtIndex(int index) {
if (index >= size || index < 0) {
return;
}
Node* cur = dummyHead;
while (index--) {
cur = cur->next;
}
Node* tmp = cur->next; // Node to delete
cur->next = cur->next->next; // Bypass the deleted node
delete tmp; // Free memory
tmp = nullptr; // Prevent dangling pointer
size--;
}
// Utility to print the linked list (for debugging)
void printLinkedList() {
Node* cur = dummyHead;
while (cur->next != nullptr) {
cout << cur->next->val << " ";
cur = cur->next;
}
cout << endl;
}
private:
int size; // Current number of nodes (excluding dummy)
Node* dummyHead; // Pointer to dummy head node
};
Notes:
- Member variables declared in
privatecan be initialized either in the constructor or directly at the point of declaration. All member functions can access them. - Before traversing the list, we define a pointer
cur. It can point to the dummy head or the first real node depending on the context. Typically, starting from the dummy head is safer because the list might be empty (no actual node).
Node* cur = dummyHead;
Node* cur = dummyHead->next; // For cases when we need the first real node
- When inserting a new node, always first connect the next of the new node to
cur->next, then setcur->nextto the new node. Reversing the order would lose the originalcur->next. - When deleting a node, save the target node in a temporary pointer
tmp, link its predecessor and successor, then deletetmpand set it tonullptrto avoid dangling pointers.