Definition: A linked list is a linear data structure consisting of a sequence of elements where each element points to the next element in the sequence.
Types of Linked Lists:
Singly Linked List: Each node contains data and a pointer to the next node.
Doubly Linked List: Each node contains data, a pointer to the next node, and a pointer to the previous node.
Circular Linked List: The last node points back to the first node, forming a circular structure.
In a linked list, the nodes are not stored in contiguous memory locations; instead, they are linked together through pointers. Each node contains data and a pointer to the next node. This non-contiguous distribution allows linked lists to dynamically allocate and deallocate memory during runtime because they do not require a single continuous block of memory. In contrast, arrays need contiguous memory space to store all elements. This distribution makes linked lists more flexible but also results in slower access times since direct indexing is not possible, and traversal from the head is required.
Time Complexity:
Insertion/Deletion at the beginning: O(1)
Insertion/Deletion at the end (for singly linked list): O(n)
Accessing an element: O(n)
Pros and Cons:
Pros: Dynamic size, efficient insertion/deletion at the beginning (for singly linked lists), and no need for contiguous memory allocation.
Cons: Inefficient random access (no direct access to elements), extra memory overhead for pointers, and traversal requires iteration.
} classMyLinkedList { int size; //!!! ListNode head; publicMyLinkedList() { size = 0; head = newListNode(0); //dummy head!!!!!!!!!! } publicintget(int index) { if(index >= size || index < 0) return -1; ListNodepointer= head; // while(index >= 0){ // pointer = pointer.next; // index--; // } /*i feel like everytime I use while to caculate the times, it goes wrong, so maybe next time just use for iteration*/ for (inti=0; i <= index; i++) { // the node on the index !!!!! pointer = pointer.next; } return pointer.val; } publicvoidaddAtHead(int val) { addAtIndex(0,val); } publicvoidaddAtTail(int val) { addAtIndex(size,val); } publicvoidaddAtIndex(int index, int val) { if (index > size) { return; } if (index < 0) { index = 0; } ListNodepointer= head; for (inti=0; i < index; i++) { // the node before the index !!!!! pointer = pointer.next; } ListNodeadd=newListNode(val); add.next = pointer.next; pointer.next = add; size++; } publicvoiddeleteAtIndex(int index) { if (index < 0 || index >= size) { return; } ListNodepointer= head; for (inti=0; i < index ; i++) { // the node before the index !!!!! pointer = pointer.next; } //if(pointer.next != null){ pointer.next = pointer.next.next;
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); */
Given a linked list, swap every two adjacent nodes and return its head. You must solve the problem without modifying the values in the list’s nodes (i.e., only nodes themselves may be changed.)
Input: head = [3,2,0,-4], pos = 1 Output: tail connects to node index 1 Explanation: There is a cycle in the linked list, where tail connects to the second node.