C++ 程序查找给定链表的最后 N 个节点的总和
给定一个链表和一个数字n 。求链表最后n 个节点的总和。
约束: 0 <= n <= 链表中的节点数。
例子:
Input: 10->6->8->4->12, n = 2
Output: 16
Sum of last two nodes:
12 + 4 = 16
Input: 15->7->9->5->16->14, n = 4
Output: 44
方法一:(使用系统调用栈的递归方式)
递归遍历链表直到结束。现在在从函数调用返回期间,将最后的n 个节点相加。总和可以累积在通过引用传递给函数或某个全局变量的某个变量中。
C++
// C++ implementation to find the sum of
// last 'n' nodes of the Linked List
#include
using namespace std;
// A Linked list node
struct Node
{
int data;
struct Node* next;
};
// Function to insert a node at the
// beginning of the linked list
void push(struct Node** head_ref,
int new_data)
{
// Allocate node
struct Node* new_node = new Node;
// Put in the data
new_node->data = new_data;
// Link the old list to the new node
new_node->next = (*head_ref);
// Move the head to point to the
// new node
(*head_ref) = new_node;
}
// Function to recursively find the sum of last
// 'n' nodes of the given linked list
void sumOfLastN_Nodes(struct Node* head,
int* n, int* sum)
{
// if head = NULL
if (!head)
return;
// Recursively traverse the remaining nodes
sumOfLastN_Nodes(head->next, n, sum);
// if node count 'n' is greater than 0
if (*n > 0)
{
// Accumulate sum
*sum = *sum + head->data;
// Reduce node count 'n' by 1
--*n;
}
}
// Utility function to find the sum of
// last 'n' nodes
int sumOfLastN_NodesUtil(struct Node* head,
int n)
{
// if n == 0
if (n <= 0)
return 0;
int sum = 0;
// Find the sum of last 'n' nodes
sumOfLastN_Nodes(head, &n, &sum);
// Required sum
return sum;
}
// Driver code
int main()
{
struct Node* head = NULL;
// Create linked list 10->6->8->4->12
push(&head, 12);
push(&head, 4);
push(&head, 8);
push(&head, 6);
push(&head, 10);
int n = 2;
cout << "Sum of last " << n <<
" nodes = " <<
sumOfLastN_NodesUtil(head, n);
return 0;
}
C++
// C++ implementation to find the sum of last
// 'n' nodes of the Linked List
#include
using namespace std;
// A Linked list node
struct Node
{
int data;
struct Node* next;
};
// Function to insert a node at the
// beginning of the linked list
void push(struct Node** head_ref,
int new_data)
{
// Allocate node
struct Node* new_node = new Node;
// Put in the data
new_node->data = new_data;
// Link the old list to the new node
new_node->next = (*head_ref);
// Move the head to point to the
// new node
(*head_ref) = new_node;
}
// Utility function to find the sum of
// last 'n' nodes
int sumOfLastN_NodesUtil(struct Node* head,
int n)
{
// if n == 0
if (n <= 0)
return 0;
stack st;
int sum = 0;
// Traverses the list from left
// to right
while (head != NULL)
{
// Push the node's data onto the
// stack 'st'
st.push(head->data);
// Move to next node
head = head->next;
}
// Pop 'n' nodes from 'st' and
// add them
while (n--)
{
sum += st.top();
st.pop();
}
// required sum
return sum;
}
// Driver code
int main()
{
struct Node* head = NULL;
// Create linked list 10->6->8->4->12
push(&head, 12);
push(&head, 4);
push(&head, 8);
push(&head, 6);
push(&head, 10);
int n = 2;
cout << "Sum of last " << n <<
" nodes = " <<
sumOfLastN_NodesUtil(head, n);
return 0;
}
C++
// C++ implementation to find the sum of last
// 'n' nodes of the Linked List
#include
using namespace std;
// A Linked list node
struct Node
{
int data;
struct Node* next;
};
// function to insert a node at the
// beginning of the linked list
void push(struct Node** head_ref,
int new_data)
{
// Alocate node
struct Node* new_node = new Node;
// Put in the data
new_node->data = new_data;
// Link the old list to the
// new node
new_node->next = (*head_ref);
// Move the head to point to the
// new node
(*head_ref) = new_node;
}
void reverseList(struct Node** head_ref)
{
struct Node* current, *prev, *next;
current = *head_ref;
prev = NULL;
while (current != NULL)
{
next = current->next;
current->next = prev;
prev = current;
current = next;
}
*head_ref = prev;
}
// Utility function to find the sum of
// last 'n' nodes
int sumOfLastN_NodesUtil(struct Node* head,
int n)
{
// if n == 0
if (n <= 0)
return 0;
// reverse the linked list
reverseList(&head);
int sum = 0;
struct Node* current = head;
// Traverse the 1st 'n' nodes of the
// reversed linked list and add them
while (current != NULL && n--)
{
// Accumulate node's data to 'sum'
sum += current->data;
// Move to next node
current = current->next;
}
// Reverse back the linked list
reverseList(&head);
// Required sum
return sum;
}
// Driver code
int main()
{
struct Node* head = NULL;
// Create linked list 10->6->8->4->12
push(&head, 12);
push(&head, 4);
push(&head, 8);
push(&head, 6);
push(&head, 10);
int n = 2;
cout << "Sum of last " << n <<
" nodes = " <<
sumOfLastN_NodesUtil(head, n);
return 0;
}
C++
// C++ implementation to find the sum of last
// 'n' nodes of the Linked List
#include
using namespace std;
// A Linked list node
struct Node
{
int data;
struct Node* next;
};
// Function to insert a node at the
// beginning of the linked list
void push(struct Node** head_ref,
int new_data)
{
// Allocate node
struct Node* new_node = new Node;
// Put in the data
new_node->data = new_data;
// Link the old list to the new node
new_node->next = (*head_ref);
// Move the head to point to the
// new node
(*head_ref) = new_node;
}
// Utility function to find the sum of
// last 'n' nodes
int sumOfLastN_NodesUtil(struct Node* head,
int n)
{
// if n == 0
if (n <= 0)
return 0;
int sum = 0, len = 0;
struct Node* temp = head;
// Calculate the length of the
// linked list
while (temp != NULL)
{
len++;
temp = temp->next;
}
// Count of first (len - n) nodes
int c = len - n;
temp = head;
// Just traverse the 1st 'c' nodes
while (temp != NULL && c--)
// move to next node
temp = temp->next;
// Now traverse the last 'n' nodes
// and add them
while (temp != NULL)
{
// Accumulate node's data to sum
sum += temp->data;
// Move to next node
temp = temp->next;
}
// Required sum
return sum;
}
// Driver code
int main()
{
struct Node* head = NULL;
// Create linked list 10->6->8->4->12
push(&head, 12);
push(&head, 4);
push(&head, 8);
push(&head, 6);
push(&head, 10);
int n = 2;
cout << "Sum of last " << n << " nodes = " <<
sumOfLastN_NodesUtil(head, n);
return 0;
}
C++
// C++ implementation to find the sum of last
// 'n' nodes of the Linked List
#include
using namespace std;
// A Linked list node
struct Node
{
int data;
struct Node* next;
};
// Function to insert a node at the
// beginning of the linked list
void push(struct Node** head_ref,
int new_data)
{
// Allocate node
struct Node* new_node = new Node;
// Put in the data
new_node->data = new_data;
// Link the old list to the new node
new_node->next = (*head_ref);
// Move the head to point to the new node
(*head_ref) = new_node;
}
// Utility function to find the sum of
// last 'n' nodes
int sumOfLastN_NodesUtil(struct Node* head,
int n)
{
// if n == 0
if (n <= 0)
return 0;
int sum = 0, temp = 0;
struct Node* ref_ptr, *main_ptr;
ref_ptr = main_ptr = head;
// Traverse 1st 'n' nodes through 'ref_ptr'
// and accumulate all node's data to 'sum'
while (ref_ptr != NULL && n--)
{
sum += ref_ptr->data;
// move to next node
ref_ptr = ref_ptr->next;
}
// Traverse to the end of the linked list
while (ref_ptr != NULL)
{
// Accumulate all node's data to 'temp'
// pointed by the 'main_ptr'
temp += main_ptr->data;
// Accumulate all node's data to 'sum'
// pointed by the 'ref_ptr'
sum += ref_ptr->data;
// Move both the pointers to their
// respective next nodes
main_ptr = main_ptr->next;
ref_ptr = ref_ptr->next;
}
// Required sum
return (sum - temp);
}
// Driver code
int main()
{
struct Node* head = NULL;
// Create linked list 10->6->8->4->12
push(&head, 12);
push(&head, 4);
push(&head, 8);
push(&head, 6);
push(&head, 10);
int n = 2;
cout << "Sum of last " << n << " nodes = " <<
sumOfLastN_NodesUtil(head, n);
return 0;
}
输出:
Sum of last 2 nodes = 16
时间复杂度: O(n),其中 n 是链表中的节点数。
辅助空间: O(n),如果正在考虑系统调用堆栈。
方法二:(使用自定义栈的迭代方式)
这是本文方法 1中解释的递归方法的迭代过程。从左到右遍历节点。遍历时将节点推送到用户定义的堆栈。然后从堆栈中弹出前n 个值并添加它们。
C++
// C++ implementation to find the sum of last
// 'n' nodes of the Linked List
#include
using namespace std;
// A Linked list node
struct Node
{
int data;
struct Node* next;
};
// Function to insert a node at the
// beginning of the linked list
void push(struct Node** head_ref,
int new_data)
{
// Allocate node
struct Node* new_node = new Node;
// Put in the data
new_node->data = new_data;
// Link the old list to the new node
new_node->next = (*head_ref);
// Move the head to point to the
// new node
(*head_ref) = new_node;
}
// Utility function to find the sum of
// last 'n' nodes
int sumOfLastN_NodesUtil(struct Node* head,
int n)
{
// if n == 0
if (n <= 0)
return 0;
stack st;
int sum = 0;
// Traverses the list from left
// to right
while (head != NULL)
{
// Push the node's data onto the
// stack 'st'
st.push(head->data);
// Move to next node
head = head->next;
}
// Pop 'n' nodes from 'st' and
// add them
while (n--)
{
sum += st.top();
st.pop();
}
// required sum
return sum;
}
// Driver code
int main()
{
struct Node* head = NULL;
// Create linked list 10->6->8->4->12
push(&head, 12);
push(&head, 4);
push(&head, 8);
push(&head, 6);
push(&head, 10);
int n = 2;
cout << "Sum of last " << n <<
" nodes = " <<
sumOfLastN_NodesUtil(head, n);
return 0;
}
输出:
Sum of last 2 nodes = 16
时间复杂度: O(n),其中 n 是链表中的节点数。
辅助空间: O(n),堆栈大小
方法3(反转链表):
以下是步骤:
- 反转给定的链表。
- 遍历反向链表的前n 个节点。
- 遍历时添加它们。
- 将链表反转回其原始顺序。
- 返回相加的总和。
C++
// C++ implementation to find the sum of last
// 'n' nodes of the Linked List
#include
using namespace std;
// A Linked list node
struct Node
{
int data;
struct Node* next;
};
// function to insert a node at the
// beginning of the linked list
void push(struct Node** head_ref,
int new_data)
{
// Alocate node
struct Node* new_node = new Node;
// Put in the data
new_node->data = new_data;
// Link the old list to the
// new node
new_node->next = (*head_ref);
// Move the head to point to the
// new node
(*head_ref) = new_node;
}
void reverseList(struct Node** head_ref)
{
struct Node* current, *prev, *next;
current = *head_ref;
prev = NULL;
while (current != NULL)
{
next = current->next;
current->next = prev;
prev = current;
current = next;
}
*head_ref = prev;
}
// Utility function to find the sum of
// last 'n' nodes
int sumOfLastN_NodesUtil(struct Node* head,
int n)
{
// if n == 0
if (n <= 0)
return 0;
// reverse the linked list
reverseList(&head);
int sum = 0;
struct Node* current = head;
// Traverse the 1st 'n' nodes of the
// reversed linked list and add them
while (current != NULL && n--)
{
// Accumulate node's data to 'sum'
sum += current->data;
// Move to next node
current = current->next;
}
// Reverse back the linked list
reverseList(&head);
// Required sum
return sum;
}
// Driver code
int main()
{
struct Node* head = NULL;
// Create linked list 10->6->8->4->12
push(&head, 12);
push(&head, 4);
push(&head, 8);
push(&head, 6);
push(&head, 10);
int n = 2;
cout << "Sum of last " << n <<
" nodes = " <<
sumOfLastN_NodesUtil(head, n);
return 0;
}
输出:
Sum of last 2 nodes = 16
时间复杂度: O(n),其中 n 是链表中的节点数。
辅助空间: O(1)
方法四(使用链表的长度):
以下是步骤:
- 计算给定链表的长度。让它成为len 。
- 首先,从头开始遍历(len – n)个节点。
- 然后遍历剩余的n 个节点,并在遍历时添加它们。
- 返回相加的总和。
C++
// C++ implementation to find the sum of last
// 'n' nodes of the Linked List
#include
using namespace std;
// A Linked list node
struct Node
{
int data;
struct Node* next;
};
// Function to insert a node at the
// beginning of the linked list
void push(struct Node** head_ref,
int new_data)
{
// Allocate node
struct Node* new_node = new Node;
// Put in the data
new_node->data = new_data;
// Link the old list to the new node
new_node->next = (*head_ref);
// Move the head to point to the
// new node
(*head_ref) = new_node;
}
// Utility function to find the sum of
// last 'n' nodes
int sumOfLastN_NodesUtil(struct Node* head,
int n)
{
// if n == 0
if (n <= 0)
return 0;
int sum = 0, len = 0;
struct Node* temp = head;
// Calculate the length of the
// linked list
while (temp != NULL)
{
len++;
temp = temp->next;
}
// Count of first (len - n) nodes
int c = len - n;
temp = head;
// Just traverse the 1st 'c' nodes
while (temp != NULL && c--)
// move to next node
temp = temp->next;
// Now traverse the last 'n' nodes
// and add them
while (temp != NULL)
{
// Accumulate node's data to sum
sum += temp->data;
// Move to next node
temp = temp->next;
}
// Required sum
return sum;
}
// Driver code
int main()
{
struct Node* head = NULL;
// Create linked list 10->6->8->4->12
push(&head, 12);
push(&head, 4);
push(&head, 8);
push(&head, 6);
push(&head, 10);
int n = 2;
cout << "Sum of last " << n << " nodes = " <<
sumOfLastN_NodesUtil(head, n);
return 0;
}
输出:
Sum of last 2 nodes = 16
时间复杂度: O(n),其中 n 是链表中的节点数。
辅助空间: O(1)
方法五(使用两个指针需要单次遍历):
维护两个指针——引用指针和主指针。初始化指向头的引用和主指针。首先,将引用指针从 head 移动到n 个节点,同时遍历累积节点的数据到某个变量,比如sum 。现在同时移动两个指针,直到引用指针到达列表的末尾,并在遍历时将所有节点的数据累积到引用指针指向的总和,并将所有节点的数据累积到主指针指向的某个变量,例如temp 。现在, (sum – temp)是最后n 个节点的所需总和。
C++
// C++ implementation to find the sum of last
// 'n' nodes of the Linked List
#include
using namespace std;
// A Linked list node
struct Node
{
int data;
struct Node* next;
};
// Function to insert a node at the
// beginning of the linked list
void push(struct Node** head_ref,
int new_data)
{
// Allocate node
struct Node* new_node = new Node;
// Put in the data
new_node->data = new_data;
// Link the old list to the new node
new_node->next = (*head_ref);
// Move the head to point to the new node
(*head_ref) = new_node;
}
// Utility function to find the sum of
// last 'n' nodes
int sumOfLastN_NodesUtil(struct Node* head,
int n)
{
// if n == 0
if (n <= 0)
return 0;
int sum = 0, temp = 0;
struct Node* ref_ptr, *main_ptr;
ref_ptr = main_ptr = head;
// Traverse 1st 'n' nodes through 'ref_ptr'
// and accumulate all node's data to 'sum'
while (ref_ptr != NULL && n--)
{
sum += ref_ptr->data;
// move to next node
ref_ptr = ref_ptr->next;
}
// Traverse to the end of the linked list
while (ref_ptr != NULL)
{
// Accumulate all node's data to 'temp'
// pointed by the 'main_ptr'
temp += main_ptr->data;
// Accumulate all node's data to 'sum'
// pointed by the 'ref_ptr'
sum += ref_ptr->data;
// Move both the pointers to their
// respective next nodes
main_ptr = main_ptr->next;
ref_ptr = ref_ptr->next;
}
// Required sum
return (sum - temp);
}
// Driver code
int main()
{
struct Node* head = NULL;
// Create linked list 10->6->8->4->12
push(&head, 12);
push(&head, 4);
push(&head, 8);
push(&head, 6);
push(&head, 10);
int n = 2;
cout << "Sum of last " << n << " nodes = " <<
sumOfLastN_NodesUtil(head, n);
return 0;
}
输出:
Sum of last 2 nodes = 16
时间复杂度: O(n),其中 n 是链表中的节点数。
辅助空间: O(1)
有关详细信息,请参阅有关查找给定链表的最后 n 个节点的总和的完整文章!