Designing a Linked List (LeetCode 707)

  • get(index): Get the value of the index-th node in the linked list. If the index is invalid, return -1.
  • addAtHead(val): 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.
  • addAtTail(val): Append a node of value val as the last element of the linked list.
  • addAtIndex(index, val): Add a node of value val before the index-th node in the linked list. If index equals 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 the index-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:

  1. Member variables declared in private can be initialized either in the constructor or directly at the point of declaration. All member functions can access them.
  2. 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
  1. When inserting a new node, always first connect the next of the new node to cur->next, then set cur->next to the new node. Reversing the order would lose the original cur->next.
  2. When deleting a node, save the target node in a temporary pointer tmp, link its predecessor and successor, then delete tmp and set it to nullptr to avoid dangling pointers.

Tags: C++ Linked List Data Structures LeetCode

Posted on Sun, 02 Aug 2026 16:56:14 +0000 by quikone