Linked List

Approach

We can use size property to easily and efficiently delete at head and tail.

Complexity

  • Time complexity:
    • get(index): Worst Time complexity $$O(n)$$
    • addAtHead(val): $O(1)$
    • addAtTail(val): $O(1)$
    • addAtIndex(index, val): Worst Time complexity $O(n)$ but for special cases where we want to read at tail, it's $O(1)$
    • deleteAtIndex(index, val): Worst Time complexity $O(n)$ but for special cases where we want to delete at tail, it's $O(1)$

Code

class Node { constructor(value) { this.value = value; this.pre = null; this.post = null; } } var MyLinkedList = function() { this.head = null; this.tail = null; this.size = 0; }; /** * @param {number} index * @return {number} */ MyLinkedList.prototype.get = function(index) { let node = this.getNodeAtIndex(index); if (node == null) { return -1; } return node.value; }; /** * @param {number} val * @return {void} */ MyLinkedList.prototype.addAtHead = function(val) { let node = new Node(val); if (this.tail == null) { this.tail = node; } if (this.head != null) { this.head.pre = node; node.post = this.head; } this.head = node; this.size++; }; /** * @param {number} val * @return {void} */ MyLinkedList.prototype.addAtTail = function(val) { let node = new Node(val); if (this.head == null) { this.head = node; } if (this.tail != null) { node.pre = this.tail; this.tail.post = node; } this.tail = node; this.size++; }; /** * @param {number} index * @param {number} val * @return {void} */ MyLinkedList.prototype.getNodeAtIndex = function(index) { let node = this.head; for (let i = 0; i < index && node != null; i++) { node = node.post; } return node; } /** * @param {number} index * @param {number} val * @return {void} */ MyLinkedList.prototype.addAtIndex = function(index, val) { if (index > this.size) { return; } if (index == 0) { return this.addAtHead(val); } if (index == this.size) { return this.addAtTail(val); } let node = this.getNodeAtIndex(index); let newNode = new Node(val); newNode.post = node; newNode.pre = node.pre; node.pre.post = newNode; node.pre = newNode; this.size++; }; MyLinkedList.prototype.deleteAtHead = function() { if (this.head != null) { // this.head.pre = null; this.head = this.head.post; this.size--; } if (this.size == 0) { this.tail = null; } } MyLinkedList.prototype.deleteAtTail = function() { if (this.tail != null) { this.tail.pre.post = null; this.tail = this.tail.pre; this.size--; } if (this.size == 0) { this.head = null; } } /** * @param {number} index * @return {void} */ MyLinkedList.prototype.deleteAtIndex = function(index) { if (index == 0) { this.deleteAtHead(); return; } if (index == this.size - 1) { this.deleteAtTail(); return; } let node = this.getNodeAtIndex(index); if (node == null) { return; } this.size--; if (this.head == node) { this.head = null; } if (this.tail == node) { this.tail = null; } if (node.pre != null) { node.pre.post = node.post; } if (node.post != null) { node.post.pre = node.pre; } }; MyLinkedList.prototype.print = function() { let node = this.head; let list = ['List:']; for ( ; node != null; ) { list.push(node.value) node = node.post; } console.log(list.join(' ')) } let list = new MyLinkedList(); list.addAtHead(1) list.print() list.addAtTail(3) list.print() list.addAtIndex(1, 2) list.print() console.log(list.get(1)) list.print() list.deleteAtIndex(0) list.print() console.log(list.get(0)) list.print()
Home | © 2026 Last Updated: Aug 09, 2026
Buy Me A Coffee