Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

created max-twin-sum-in-list #1837 #1900

Merged
merged 3 commits into from
Nov 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 152 additions & 0 deletions docs/linked-list/max-twin-sum-of-linked-list.md
Original file line number Diff line number Diff line change
@@ -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 <stdio.h>
#include <stdlib.h>

// 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;
}
```
119 changes: 119 additions & 0 deletions docs/linked-list/next-greater-node-in-linked-list.md
Original file line number Diff line number Diff line change
@@ -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 <iostream>
#include <vector>
#include <stack>
using namespace std;

struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(nullptr) {}
};

class Solution {
public:
vector<int> nextLargerNodes(ListNode* head) {
vector<int> values;

// Convert linked list to an array of values
while (head) {
values.push_back(head->val);
head = head->next;
}

int n = values.size();
vector<int> result(n, 0); // Initialize result array with 0s
stack<int> 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<int>& 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<int> list_values = {2, 1, 5};
ListNode* head = createLinkedList(list_values);

Solution solution;
vector<int> result = solution.nextLargerNodes(head);

cout << "Next greater nodes: ";
for (int val : result) {
cout << val << " ";
}
cout << endl;

return 0;
}
```
123 changes: 123 additions & 0 deletions docs/linked-list/swapping-node-in-a-linked-list-at-kth-node.md
Original file line number Diff line number Diff line change
@@ -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 <iostream>
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;
}
``
Loading