diff --git a/docs/linked-list/max-twin-sum-of-linked-list.md b/docs/linked-list/max-twin-sum-of-linked-list.md new file mode 100644 index 000000000..678a608b2 --- /dev/null +++ b/docs/linked-list/max-twin-sum-of-linked-list.md @@ -0,0 +1,152 @@ +--- +id: max-twin-sum +sidebar_position: 1 +title: "Maximum Twin Sum of Linked List" +description: "This tutorial explains how to find the maximum twin sum in a linked list using C." +sidebar_label: "Max Twin Sum" +tags: [dsa, linked-lists, c] +--- + +# Maximum Twin Sum of Linked List + +## Problem Statement + +In a linked list with an even number of nodes (size n), certain nodes are designated as "twins." Specifically, the i-th node (starting from index 0) is paired with the (n−1−i)-th node as its twin, for all i such that 0≤i≤(n/2)-1. In other words, the first node is paired with the last node, the second node with the second-last node, and so on, up to the midpoint of the list. + +For example, in a linked list of 4 nodes, node 0 is the twin of node 3, and node 1 is the twin of node 2. Each pair has a "twin sum," which is simply the sum of the values of the two nodes in the pair. The goal is to find the maximum twin sum among all such twin pairs in the linked list. + +### Example + +**Input:** +- `head = [5,4,2,1]` + +**Output:** +- `6` + +**Explanation:** +- Nodes 0 and 1 are the twins of nodes 3 and 2, respectively. +- All twin pairs have a twin sum of 6. +- There are no other nodes with twins in the linked list. +- Thus, the maximum twin sum of the linked list is 6. + +## Solution Explanation + +To solve this problem efficiently: + +1. **Reverse the Second Half of the List**: + - First, we traverse the list to find its middle point. + - We then reverse the second half of the list so that we can easily compare the corresponding twin nodes. + +2. **Calculate Twin Sum**: + - After reversing the second half, we can iterate through the first half of the list and the reversed second half simultaneously to compute the twin sum for each pair. + - Keep track of the maximum twin sum as we traverse both halves. + +3. **Return Maximum Twin Sum**: + - Finally, after traversing all pairs, return the maximum twin sum. + +### Time and Space Complexity: +- **Time Complexity**: `O(n)`, where `n` is the number of nodes in the list. We traverse the list twice: once for finding the middle and reversing the second half, and once for calculating the twin sums. +- **Space Complexity**: `O(1)`, as we modify the list in place and do not use any extra data structures. + +## Code Implementation + +Here’s the C code for finding the maximum twin sum in a linked list: + +```c +#include +#include + +// Definition for singly-linked list. +struct ListNode { + int val; + struct ListNode *next; +}; + +// Function to reverse the linked list +struct ListNode* reverseList(struct ListNode* head) { + struct ListNode* prev = NULL; + struct ListNode* curr = head; + struct ListNode* next = NULL; + + while (curr != NULL) { + next = curr->next; + curr->next = prev; + prev = curr; + curr = next; + } + return prev; +} + +// Function to find the maximum twin sum +int pairSum(struct ListNode* head) { + struct ListNode* slow = head; + struct ListNode* fast = head; + + // Find the middle of the list using slow and fast pointers + while (fast != NULL && fast->next != NULL) { + slow = slow->next; + fast = fast->next->next; + } + + // Reverse the second half of the list + struct ListNode* secondHalf = reverseList(slow); + struct ListNode* firstHalf = head; + + int maxSum = 0; + + // Calculate the twin sum for each pair + while (secondHalf != NULL) { + int currentSum = firstHalf->val + secondHalf->val; + maxSum = (currentSum > maxSum) ? currentSum : maxSum; + + firstHalf = firstHalf->next; + secondHalf = secondHalf->next; + } + + return maxSum; +} + +// Helper function to create a linked list from an array +struct ListNode* createLinkedList(int* values, int size) { + struct ListNode* dummy = (struct ListNode*)malloc(sizeof(struct ListNode)); + struct ListNode* current = dummy; + for (int i = 0; i < size; i++) { + current->next = (struct ListNode*)malloc(sizeof(struct ListNode)); + current = current->next; + current->val = values[i]; + } + return dummy->next; +} + +// Helper function to print a linked list +void printLinkedList(struct ListNode* head) { + struct ListNode* current = head; + while (current != NULL) { + printf("%d", current->val); + if (current->next != NULL) { + printf("->"); + } + current = current->next; + } + printf("\n"); +} + +int main() { + // Example input + int values[] = {5, 4, 2, 1}; + + struct ListNode* head = createLinkedList(values, 4); + + // Print the original list + printf("Original List: "); + printLinkedList(head); + + // Find the maximum twin sum + int result = pairSum(head); + + // Output the result + printf("Maximum Twin Sum: %d\n", result); + + return 0; +} +``` \ No newline at end of file diff --git a/docs/linked-list/next-greater-node-in-linked-list.md b/docs/linked-list/next-greater-node-in-linked-list.md new file mode 100644 index 000000000..190211e16 --- /dev/null +++ b/docs/linked-list/next-greater-node-in-linked-list.md @@ -0,0 +1,119 @@ +--- +id: next-greater-node-in-linked-list +sidebar_position: 1 +title: "Next Greater Node in Linked List" +description: "This tutorial explains how to find the next greater node in a linked list using C++." +sidebar_label: "Next Greater Node" +tags: [dsa, linked-lists, cpp] +--- + +# Next Greater Node in Linked List + +## Problem Statement + +Given the head of a linked list with `n` nodes, for each node, find the value of the next node that is strictly greater. If no such node exists, return 0 for that position. + +Return an integer array `answer` where `answer[i]` is the value of the next greater node of the `i`th node (1-indexed). + +### Example + +**Input:** +- `head = [2,1,5]` + +**Output:** +- `[5,5,0]` + +### Constraints +- The linked list can have up to `10^4` nodes. +- Each node contains a non-negative integer value. + +## Solution Explanation + +To solve the problem: +1. **Traverse and Store Values**: + - First, convert the linked list to an array of values. This allows for easy access and processing. +2. **Next Greater Element with Stack**: + - Use a stack to keep track of indices of elements that are waiting for a "next greater" element. + - Traverse the array, and for each value, check if it’s greater than the values represented by indices in the stack. + - If so, pop indices from the stack and assign this value as the "next greater" for each of these indices. + - Push the current index onto the stack if it doesn't have a greater element in the remainder of the array. +3. **Final Result**: + - Return the result array where each position `i` contains the next greater node for the node `i`, or 0 if no greater value exists. + +### Complexity +- **Time Complexity**: `O(n)`, where `n` is the number of nodes, as each node is processed once. +- **Space Complexity**: `O(n)`, for storing values in the array and using the stack. + +## Code Implementation + +Here’s the C++ code for finding the next greater node in a linked list: + +```cpp +#include +#include +#include +using namespace std; + +struct ListNode { + int val; + ListNode *next; + ListNode(int x) : val(x), next(nullptr) {} +}; + +class Solution { +public: + vector nextLargerNodes(ListNode* head) { + vector values; + + // Convert linked list to an array of values + while (head) { + values.push_back(head->val); + head = head->next; + } + + int n = values.size(); + vector result(n, 0); // Initialize result array with 0s + stack s; // Stack to track indices for next greater element + + // Traverse the values array to find next greater element for each node + for (int i = 0; i < n; ++i) { + // Check if current value is greater than values at indices in the stack + while (!s.empty() && values[i] > values[s.top()]) { + result[s.top()] = values[i]; + s.pop(); + } + s.push(i); // Push the current index + } + + return result; // Result array with next greater values + } +}; + +// Helper function to create a linked list from an array +ListNode* createLinkedList(const vector& values) { + ListNode dummy(0); + ListNode* current = &dummy; + for (int value : values) { + current->next = new ListNode(value); + current = current->next; + } + return dummy.next; +} + +// Main function for testing +int main() { + vector list_values = {2, 1, 5}; + ListNode* head = createLinkedList(list_values); + + Solution solution; + vector result = solution.nextLargerNodes(head); + + cout << "Next greater nodes: "; + for (int val : result) { + cout << val << " "; + } + cout << endl; + + return 0; +} +``` diff --git a/docs/linked-list/swapping-node-in-a-linked-list-at-kth-node.md b/docs/linked-list/swapping-node-in-a-linked-list-at-kth-node.md new file mode 100644 index 000000000..76b9276f4 --- /dev/null +++ b/docs/linked-list/swapping-node-in-a-linked-list-at-kth-node.md @@ -0,0 +1,123 @@ +--- +id: swap-kth-nodes +sidebar_position: 1 +title: "Swap kth Node from Beginning and End" +description: "This tutorial explains how to swap the kth node from the beginning and kth node from the end of a linked list." +sidebar_label: "Linked List Swapping" +tags: [dsa, linked-lists] +--- + +# Swap kth Node from Beginning and End + +## Problem Statement + +Given the head of a linked list and an integer `k`, return the head of the linked list after swapping the values of the kth node from the beginning and the kth node from the end (the list is 1-indexed). + +### Example + +**Input:** +- `head = [1, 2, 3, 4, 5]` +- `k = 2` + +**Output:** +- `[1, 4, 3, 2, 5]` + +## Solution Explanation + +To swap the kth node from the beginning with the kth node from the end: +1. **Find the kth node from the beginning**: + - Traverse the list until the kth node is reached using a pointer (`first`). +2. **Find the kth node from the end**: + - Traverse the list again but from the head and stop at the `n-k+1`th node using a pointer (`second`), where `n` is the length of the list. +3. **Swap the values of the two nodes**: + - Swap the `val` fields of the two nodes. + +### Complexity +- **Time Complexity**: `O(n)`, where `n` is the number of nodes in the list, as we traverse the list twice. +- **Space Complexity**: `O(1)`, as we use only a few extra pointers for the operation. + +## Code Implementation + +Here’s the C++ code to swap the kth node from the beginning and the kth node from the end: + +```cpp +#include +using namespace std; + +struct ListNode { + int val; + ListNode *next; + ListNode(int x) : val(x), next(nullptr) {} +}; + +class Solution { +public: + ListNode* swapNodes(ListNode* head, int k) { + ListNode *first = head, *second = head, *current = head; + int length = 0; + + // Find the length of the list + while (current != nullptr) { + length++; + current = current->next; + } + + // Find the kth node from the beginning + for (int i = 1; i < k; i++) { + first = first->next; + } + + // Find the kth node from the end + for (int i = 1; i < length - k + 1; i++) { + second = second->next; + } + + // Swap the values of the two nodes + swap(first->val, second->val); + + return head; + } +}; + +// Helper function to create a linked list from an array +ListNode* createLinkedList(int* values, int size) { + ListNode* dummy = new ListNode(0); + ListNode* current = dummy; + for (int i = 0; i < size; i++) { + current->next = new ListNode(values[i]); + current = current->next; + } + return dummy->next; +} + +// Helper function to print a linked list +void printLinkedList(ListNode* head) { + while (head != nullptr) { + cout << head->val; + if (head->next != nullptr) { + cout << "->"; + } + head = head->next; + } + cout << endl; +} + +int main() { + // Example input + int listValues[] = {1, 2, 3, 4, 5}; + int k = 2; + + ListNode* head = createLinkedList(listValues, 5); + + cout << "Original List: "; + printLinkedList(head); + + Solution solution; + ListNode* modifiedHead = solution.swapNodes(head, k); + + cout << "Modified List: "; + printLinkedList(modifiedHead); + + return 0; +} +`` \ No newline at end of file