题目
给定一个链表,请判断该链表是否为回文结构。
回文是指该字符串正序逆序完全一致。
数据范围: 链表节点数 0≤n≤\(10^5\) ,链表中每个节点的值满足 ∣val∣≤\(10^7\)
示例1
输入:
{1}
返回值:
true
示例2
输入:
{2,1}
返回值:
false
说明:
2->1
示例3
输入:
{1,2,2,1}
返回值:
true
说明:
1->2->2->1
思路1
因为需要判断是否为回文结构,所以要比较头尾的数据,而链表无法随机查询数据,所以可以先将链表存入一个数组中,然后比较正序和反序的节点元素。
解答代码1
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) : val(x), next(nullptr) {}
* };
*/
#include <vector>
class Solution {
public:
/**
* @param head ListNode类 the head
* @return bool布尔型
*/
bool isPail(ListNode* head) {
// write code here
if (head == nullptr) {
return false;
}
std::vector<int> tmp;
auto p = head;
//将链表元素取出一次放入数组
while (p != nullptr) {
tmp.push_back(p->val);
p = p->next;
}
auto it = tmp.rbegin();
while (it != tmp.rend()) {
if (head->val != *it) {
//正向遍历与反向遍历不相同,则不是回文结构
return false;
}
head = head->next;
it++;
}
return true;
}
};
思路2
使用快慢指针,快指针的速度为慢指针的两倍,当快指针到达链表尾部时,慢指针到达中间位置,将慢指针之后的部分进行反转,再与前半部分进行比较。(需要注意链表个数是奇数和偶数的区别)
解答代码1
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) : val(x), next(nullptr) {}
* };
*/
#include <vector>
class Solution {
public:
/**
* @param head ListNode类 the head
* @return bool布尔型
*/
bool isPail(ListNode* head) {
// write code here
if (head == nullptr) {
return false;
}
auto fast = head;
auto low = head;
//通过快慢指针找到中点
while (fast != nullptr && fast->next != nullptr) {
fast = fast->next->next;
low = low->next;
}
//如果fast不为空,说明链表的长度是奇数个
if (fast != nullptr) {
low = low->next;
}
//反转后半部分链表
auto rev = reverse(low);
while (rev != nullptr) {
if (head->val != rev->val) {
return false;
}
head = head->next;
rev = rev->next;
}
return true;
}
ListNode* reverse(ListNode* head) {
if (head == nullptr) {
return nullptr;
}
ListNode* pre = nullptr;
auto cur = head;
while (cur != nullptr) {
auto tmp = cur->next;
cur->next = pre;
pre = cur;
cur = tmp;
}
return pre;
}
};
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。