回文链表

本文介绍了一种在O(n)时间复杂度和O(1)空间复杂度下判断链表是否为回文结构的算法。通过将链表后半部分逆序并与前半部分进行比较,实现链表回文检测。文章提供了详细的代码实现,并在最后恢复了链表的原始状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:
给定一个链表的头结点head,判断该链表是否为回文结构
例如:
1->2->1 返回 true;
1->2->3 返回 false; 要求时间复杂度为O(n),空间复杂度为O(1);
这道题目不能另设一个栈空间,只能通过链表标记指针将链表后半部分 逆序,在比较 相等为回文链表 不同返回false;
需要注意的是最后需要回复链表为之前的状态
代码:

#include <cstdio>
#include <iostream>
using namespace std;
struct node
{
	int data;
	struct node* next;
};
bool isPalindrome(node *head)
{
	if (head == NULL || head->next == NULL)//如果结点为空或只有一个结点则为回文链表
	{
		return true;
	}
	node *n1 = head;//走一步
	node *n2 = head;//走两步
	while (n2->next != NULL&&n2->next->next != NULL)
	{
		n1 = n1->next;
		n2 = n2->next->next;
	}//循环结束n1指向中点 n2指向尾结点
	n2 = n1->next;//n2指向后半部分第一个结点
	n1->next = NULL;//复用n1结点 将后半部分结点逆序
	node *n3=NULL;
	while (n2 != NULL)
	{
		n3 = n2->next;
		n2->next = n1;
		n1 = n2;
		n2 = n3;
	}//头插法循环结束后n1指向后半部分第一个结点 n2指向尾结点
	n2 = head;
	n3 = n1;//n3保存后半部分第一个节点的位置;
	bool res = true;
	while (n1 != NULL&& n2 != NULL)
	{
		if (n1->data != n2->data)
		{
			res = false;
			break;
		}
		n1 = n1->next;
		n2 = n2->next;
	}
	//例如head1当前顺序为1 2 3 1 2 同时n3指向后半部分的1 要恢复链表为 1 2 3 2 1
	n1 = n3->next;
	n3->next = NULL;
	while (n1 != NULL)
	{
		n2 = n1->next;
		n1->next = n3;
		n3 = n1;
		n1 = n2;
	}
	return res;
}
int main()
{
	node *head1 ,*head2;
	head1 = new node;
	head1->data = 1;
	head1->next = new node;
	head1->next->data = 2;
	head1->next->next = new node;
	head1->next->next->data = 3;
	head1->next->next->next = new node;
	head1->next->next->next->data = 2;
	head1->next->next->next->next = new node;
	head1->next->next->next->next->data = 1;
	head1->next->next->next->next->next = NULL;
	if (isPalindrome(head1)==true)
	{
		cout << "head1 = Yes" << endl;
	}
	else
	{
		cout << "head1 = No" << endl;
	}
	head2 = new node;
	head2->next = new node;
	head2->next->next = new node;
	head2->next->next->next = new node;
	head2->data = 1;
	head2->next->data = 2;
	head2->next->next->data = 3;
	head2->next->next->next->data = 2;
	head2->next->next->next->next = NULL;
	if (isPalindrome(head2)==true)
	{
		cout << "head2 = Yes" << endl;
	}
	else
	{
		cout << "head2 = No" << endl;
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VictorierJwr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值