目录
注:该题在王道书第58页的解答似乎有一些问题,运行出来只能计算两端的结果,而无法算出中间的值。(仅代表个人观点)
题目
设有一个长度n(n为偶数)的不带头结点的单链表,且结点值都大于0,设计算法求这个单链表的最大孪生和。孪生和定义为一个结点值与其孪生结点值之和,对于第1个结点(从0开始),其孪生结点为第n-i-1个结点。
核心代码
// 计算最大孪生和
int maxTwinSum(Node* head) {
//如果链表为空则返回0
if(head==NULL){
return 0;
}
//计算链表长度
int n=0;
Node *temp=head;
while(temp!=NULL){
n++;
temp=temp->next;
}
//确保n为偶数
if(n%2!=0){
return -1;//如果n不是偶数,返回错误
}
//使用数组存储结点(关键:使用数组存储链表中的数据。更加的方便操作)
int* values=(int *)malloc(n*sizeof(int));
temp=head;
for(int i=0;i<n;i++){
values[i]=temp->data;
temp=temp->next;
}
//计算最大孪生和(只需要遍历前半部分的数据)
int maxSum=0;
for(int i=0;i<n/2;i++){
int twinSum=values[i]+values[n-i-1];
if(twinSum>maxSum){
maxSum=twinSum;
}
}
free(values);
return maxSum;
}
完整代码
#include <stdio.h>
#include <stdlib.h>
// 定义链表节点
typedef struct Node {
int data;
struct Node* next;
} Node;
// 创建新节点
Node* createNode(int data) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
// 插入节点到链表的末尾
void insert(Node** head, int data) {
Node* newNode = createNode(data);
if (*head == NULL) {
*head = newNode;
return;
}
Node* temp = *head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
}
// 计算最大孪生和
int maxTwinSum(Node* head) {
//如果链表为空则返回0
if(head==NULL){
return 0;
}
//计算链表长度
int n=0;
Node *temp=head;
while(temp!=NULL){
n++;
temp=temp->next;
}
//确保n为偶数
if(n%2!=0){
return -1;//如果n不是偶数,返回错误
}
//使用数组存储结点(关键:使用数组存储链表中的数据。更加的方便操作)
int* values=(int *)malloc(n*sizeof(int));
temp=head;
for(int i=0;i<n;i++){
values[i]=temp->data;
temp=temp->next;
}
//计算最大孪生和(只需要遍历前半部分的数据)
int maxSum=0;
for(int i=0;i<n/2;i++){
int twinSum=values[i]+values[n-i-1];
if(twinSum>maxSum){
maxSum=twinSum;
}
}
free(values);
return maxSum;
}
// 打印链表
void printList(Node* head) {
Node* current = head;
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
printf("\n");
}
int main() {
Node* head = NULL;
// 插入节点
insert(&head, 1);
insert(&head, 2);
insert(&head, 3);
insert(&head, 4);
insert(&head, 6);
insert(&head, 2);
printf("链表:");
printList(head);
int maxSum = maxTwinSum(head);
if (maxSum != -1) {
printf("最大孪生和为:%d\n", maxSum);
} else {
printf("链表长度不是偶数,无法计算孪生和。\n");
}
return 0;
}
示例
链表:1 2 3 4 6 2
最大孪生和为:8