Sponsored
Sponsored
In this approach, you will design a singly linked list where each node has a value and a pointer to the next node. This type of list is simple and efficient for certain operations, especially when traversing only forwards is sufficient.
Time Complexity:
- get
: O(n)
- addAtHead
: O(1)
- addAtTail
: O(n)
- addAtIndex
: O(n)
- deleteAtIndex
: O(n)
Space Complexity: O(n), where n is the number of nodes in the list.
1#include <stdio.h>
2#include <stdlib.h>
3
4struct Node {
5 int val;
6 struct Node* next;
7};
8
9struct MyLinkedList {
10 struct Node* head;
11};
12
13struct MyLinkedList* myLinkedListCreate() {
14 struct MyLinkedList* obj = (struct MyLinkedList*)malloc(sizeof(struct MyLinkedList));
15 obj->head = NULL;
16 return obj;
17}
18
19void myLinkedListAddAtHead(struct MyLinkedList* obj, int val) {
20 struct Node* node = (struct Node*)malloc(sizeof(struct Node));
21 node->val = val;
22 node->next = obj->head;
23 obj->head = node;
24}
25
26void myLinkedListAddAtTail(struct MyLinkedList* obj, int val) {
27 struct Node* node = (struct Node*)malloc(sizeof(struct Node));
28 node->val = val;
29 node->next = NULL;
30 if (obj->head == NULL) {
31 obj->head = node;
32 } else {
33 struct Node* current = obj->head;
34 while (current->next != NULL) {
35 current = current->next;
36 }
37 current->next = node;
38 }
39}
40
41int myLinkedListGet(struct MyLinkedList* obj, int index) {
42 struct Node* current = obj->head;
43 int i = 0;
44 while (current != NULL && i < index) {
45 current = current->next;
46 i++;
47 }
48 return (current == NULL) ? -1 : current->val;
49}
50
51void myLinkedListAddAtIndex(struct MyLinkedList* obj, int index, int val) {
52 if(index == 0) {
53 myLinkedListAddAtHead(obj, val);
54 return;
55 }
56 struct Node* current = obj->head;
57 for(int i = 0; current != NULL && i < index - 1; i++) {
58 current = current->next;
59 }
60 if (current == NULL) return;
61 struct Node* node = (struct Node*)malloc(sizeof(struct Node));
62 node->val = val;
63 node->next = current->next;
64 current->next = node;
65}
66
67void myLinkedListDeleteAtIndex(struct MyLinkedList* obj, int index) {
68 struct Node* current = obj->head;
69 if (index == 0 && current != NULL) {
70 obj->head = current->next;
71 free(current);
72 return;
73 }
74 struct Node* prev = NULL;
75 for (int i = 0; current != NULL && i < index; i++) {
76 prev = current;
77 current = current->next;
78 }
79 if(current == NULL) return;
80 prev->next = current->next;
81 free(current);
82}
83
84void myLinkedListFree(struct MyLinkedList* obj) {
85 struct Node* current = obj->head;
86 while (current != NULL) {
87 struct Node* next = current->next;
88 free(current);
89 current = next;
90 }
91 free(obj);
92}
The above code implements a singly linked list in C. It provides functions to add nodes at the head, tail, a specific index, get the value at an index, and delete a node at an index. The linked list maintains a head pointer and nodes are dynamically allocated using malloc
.
This approach designs a doubly linked list, allowing traversal both forwards and backwards. Each node maintains a reference to both the next and previous node, facilitating operations such as adding or removing nodes from either end more efficiently.
Time Complexity:
- get
: O(n)
- addAtHead
: O(1)
- addAtTail
: O(n)
- addAtIndex
: O(n)
- deleteAtIndex
: O(n)
Space Complexity: O(n), where n is the number of nodes in the list.
1
The Python solution features a doubly linked list implementation where each node contains pointers to both previous and next nodes, improving operations for changes at arbitrary indices.