在链表中找到前后等距的最大成对和
给定一个长度为N的链表lis ,其中N是偶数。任务是最大化给定链表前端和后端的两个等距节点的总和。
Note: Two nodes (i and j) are equidistant from both ends if the distance of ith node from front is same as distance of jth node from back.
例子:
Input: lis = {5, 4, 2, 1}
Output: 6
Explanation: The nodes with pairs present in this linked list are:
Node 0 and node 3 are equidistant having a sum of 5 + 1 = 6.
Node 1 and node 2 are equidistant having a sum of 4 + 2 = 6.
Thus, the maximum sum of equidistant nodes of the linked list is max(6, 6) = 6.
Input: lis = {4, 2, 2, 3}
Output: 7
Explanation: The nodes with pairs present in this linked list are:
Node 0 and node 3 are equidistant having a sum of 4 + 3 = 7.
Node 1 and node 2 are equidistant having a sum of 2 + 2 = 4.
Thus, the maximum sum of equidistant nodes of the linked list is max(7, 4) = 7.
方法:解决方案是将链表分成相等的两半,然后使用两个指针的方法。请按照以下步骤解决问题:
- 获取中间并将链表分成两部分。
- 反转第二部分,用于正向遍历它。
- 遍历两个部分并获得最大和。
- 通过再次连接部件来再次恢复链接列表,以获得良好的实践。
下面是上述方法的实现。
C++
// C++ code to implement above approach
#include
using namespace std;
// Structure of a node
struct ListNode {
int val;
ListNode* next;
ListNode()
: val(0), next(nullptr)
{
}
ListNode(int x)
: val(x), next(nullptr)
{
}
ListNode(int x, ListNode* next)
: val(x), next(next)
{
}
};
// Function to add node in linked list
void push(struct ListNode** head_ref,
int new_data)
{
// Allocate node
struct ListNode* new_node
= new ListNode;
// Put in the data
new_node->val = new_data;
// Link the old list off the new node
new_node->next = (*head_ref);
// Move the head to point the new node
(*head_ref) = new_node;
}
// Function for reversing the linked list
void reverse(ListNode** head)
{
ListNode *curr = *head, *prev = 0, *nxt;
while (curr)
nxt = curr->next,
curr->next = prev,
prev = curr,
curr = nxt;
*head = prev;
}
// Function to find the maximum sum
// of equidistant elements
int pairSum(ListNode* head)
{
// Get mid and separate
// the linked list into two parts
ListNode *prev = 0, *slow = head,
*fast = head;
// Find mid
while (fast and fast->next)
prev = slow, slow = slow->next,
fast = fast->next->next;
// Separate them
prev->next = 0;
// Reverse the second part,
// for traversing it
// in forward direction
reverse(&slow);
// Traverse in both parts and
// get the maximum sum
int sum = 0;
ListNode *ptr1 = head, *ptr2 = slow;
while (ptr1)
sum = max(sum, (ptr1->val
+ ptr2->val)),
ptr1 = ptr1->next, ptr2
= ptr2->next;
// Recover the Linked List again, by
// connection the parts again
reverse(&slow);
prev->next = slow;
// Return sum
return sum;
}
// Driver code
int main()
{
struct ListNode* head = NULL;
push(&head, 4);
push(&head, 2);
push(&head, 2);
push(&head, 3);
cout << pairSum(head);
return 0;
}
Java
// Java code to implement above approach
class GFG{
// Structure of a node
static class ListNode {
int val;
ListNode next;
ListNode()
{
this(0);
}
ListNode(int x)
{
this.val = x;
this.next = null;
}
ListNode(int x, ListNode next)
{
this.val = x;
this.next = next;
}
};
// Function to add node in linked list
static ListNode push(ListNode head_ref,
int new_data)
{
// Allocate node
ListNode new_node
= new ListNode();
// Put in the data
new_node.val = new_data;
// Link the old list off the new node
new_node.next = head_ref;
// Move the head to point the new node
head_ref = new_node;
return head_ref;
}
// Function for reversing the linked list
static ListNode reverse(ListNode head)
{
ListNode curr = head, prev = new ListNode(), nxt=new ListNode();
while (curr.next!=null) {
nxt = curr.next;
curr.next = prev;
prev = curr;
curr = nxt;
}
head = prev;
return head;
}
// Function to find the maximum sum
// of equidistant elements
static int pairSum(ListNode head)
{
// Get mid and separate
// the linked list into two parts
ListNode prev = new ListNode(), slow = head,
fast = head;
// Find mid
while (fast!=null && fast.next!=null) {
prev = slow;
slow = slow.next;
fast = fast.next.next;
}
// Separate them
prev.next = new ListNode();
// Reverse the second part,
// for traversing it
// in forward direction
slow = reverse(slow);
// Traverse in both parts and
// get the maximum sum
int sum = 0;
ListNode ptr1 = head, ptr2 = slow;
while (ptr1!=null) {
sum = Math.max(sum, (ptr1.val
+ ptr2.val));
ptr1 = ptr1.next;
ptr2 = ptr2.next;
}
// Recover the Linked List again, by
// connection the parts again
slow = reverse(slow);
prev.next = slow;
// Return sum
return sum;
}
// Driver code
public static void main(String[] args)
{
ListNode head = new ListNode();
head = push(head, 4);
head = push(head, 2);
head = push(head, 2);
head = push(head, 3);
System.out.print(pairSum(head));
}
}
// This code is contributed by 29AjayKumar
C#
// C# code to implement above approach
using System;
public class GFG{
// Structure of a node
class ListNode {
public int val;
public ListNode next;
public ListNode()
{
new ListNode(0);
}
public ListNode(int x)
{
this.val = x;
this.next = null;
}
public ListNode(int x, ListNode next)
{
this.val = x;
this.next = next;
}
};
// Function to add node in linked list
static ListNode push(ListNode head_ref,
int new_data)
{
// Allocate node
ListNode new_node
= new ListNode();
// Put in the data
new_node.val = new_data;
// Link the old list off the new node
new_node.next = head_ref;
// Move the head to point the new node
head_ref = new_node;
return head_ref;
}
// Function for reversing the linked list
static ListNode reverse(ListNode head)
{
ListNode curr = head, prev = new ListNode(), nxt=new ListNode();
while (curr.next!=null) {
nxt = curr.next;
curr.next = prev;
prev = curr;
curr = nxt;
}
head = prev;
return head;
}
// Function to find the maximum sum
// of equidistant elements
static int pairSum(ListNode head)
{
// Get mid and separate
// the linked list into two parts
ListNode prev = new ListNode(), slow = head,
fast = head;
// Find mid
while (fast!=null && fast.next!=null) {
prev = slow;
slow = slow.next;
fast = fast.next.next;
}
// Separate them
prev.next = new ListNode();
// Reverse the second part,
// for traversing it
// in forward direction
slow = reverse(slow);
// Traverse in both parts and
// get the maximum sum
int sum = 0;
ListNode ptr1 = head, ptr2 = slow;
while (ptr1!=null) {
sum = Math.Max(sum, (ptr1.val
+ ptr2.val));
ptr1 = ptr1.next;
ptr2 = ptr2.next;
}
// Recover the Linked List again, by
// connection the parts again
slow = reverse(slow);
prev.next = slow;
// Return sum
return sum;
}
// Driver code
public static void Main(String[] args)
{
ListNode head = new ListNode();
head = push(head, 4);
head = push(head, 2);
head = push(head, 2);
head = push(head, 3);
Console.Write(pairSum(head));
}
}
// This code is contributed by shikhasingrajput
7
时间复杂度: O(N)
辅助空间: O(1)