目录
题目
描述
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
测试样例:
1->2->2->1
返回:true
图解
代码
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
#include <cstddef>
typedef struct ListNode ListNode;
class PalindromeList {
public:
struct ListNode* middleNode(struct ListNode* head) {
// 思路快慢指针
// 都从都i一个节点开始
ListNode* fast = head;
ListNode* slow = head;
// 循环遍历
while ( fast &&
fast->next) {//这边我们得先检查fast再检查fast->next //(偶数)如果我们先检查fast->next,他会访问不存在地址从而导致野指针,而fast如果为NULL就为假就不会判断第二个条件
slow = slow->next; // 走一步
fast = fast->next->next; // 走两步
}
return slow;//返回比较慢得指针
}
//====================================
struct ListNode* reverseList(struct ListNode* head) {
// 思路:通过创建三个指针(n1,n2,n3),来进行调动next指针的指向来翻转链表
// 根据题目给出的提示我们可以看出链表可能为空
if (head == NULL) {
return head;
}
// 创建三个指针
ListNode* n1, *n2, *n3;
// 初始化
n1 = NULL;
n2 = head;
n3 = n2->next;
// 利用循环实现翻转
while (n2) { // 头判断是否为NULL
// 开始倒叙
n2->next = n1;//将head指向n1
//通过移动指针,再加上一直循环将我们每个节点的next指针指向前一个节点这样我们就实现了倒叙
n1 = n2;
n2 = n3;
if (n3) // 判断n3是否已经到达NULL
n3 = n3->next;
}
return n1; // 返回head节点
}
bool chkPalindrome(ListNode* A) {
ListNode* mid = middleNode(A); //找中间节点
ListNode* rmid = reverseList(mid);//逆置
//判断是否相等
while (A && rmid) {
//判断
if (A->val != rmid->val) { //如果不想等就不是回文结构
return false;
}
A = A->next;
rmid = rmid->next;
}
return true;
}
};