题目地址:力扣
解法1:将链表复制到数组里再从两头比对
class Solution {
public:
bool isPalindrome(ListNode* head) {
vector<int> listvec;
// 把链表中元素都插入数组
while (head!= nullptr)
{
listvec.push_back(head->val);
head = head->next;
}
// 一个迭代器从头,一个迭代器从尾
auto it_head = listvec.begin();
auto it_back = listvec.end() - 1;
// 若迭代器相遇了则说明都检查完了,可以返回true
while (it_back - it_head > 0)
{
// 检查到值不相等就返回false
if ((*it_head++) != (*it_back--))
return false;
}
return true;
}
};
解法2:递归法
解法1的问题在于要开辟额外数组,递归虽然不用开辟额外空间,但是需要占用系统栈的空间,而且效率可能还更差。
这种方法需要一个额外的节点用来保存链表头结点,并且在递归到达最里层的时候往后走,这样就可以实现头指针向后,尾指针向前对比。
class Solution {
public:
// 递归函数
bool check(ListNode* curNode)
{
// 若当前节点不为空
if (curNode != nullptr)
{
// 因为是从下往上的,判断检查更里面的递归是否是false,是的话直接返回false
if (!check(curNode->next))
return false;
// 更里面是true就检查当前层的情况
if (curNode->val != headnode->val)
return false;
// 当前层也满足的话就把headnode往后
headnode = headnode->next;
}
// 当前节点为空,或者经历了上面的检查以后返回true
return true;
}
bool isPalindrome(ListNode* head) {
headnode = head;
return check(head);
}
ListNode* headnode;
};
解法3:快慢指针法
思路:要判断回文链表,可以把链表的后面部分反转,然后再对比就行了。而要找到链表中部,就需要采用快慢指针的方法,快指针一次走两步,慢指针一次走一步,如果快指针的next不为空就走一步,如果next->next不为空就再走一步,同时走第二步的时候慢指针也走一步。这样慢指针指到中间的时候,快指针正好指到表尾。然后从慢指针的next开始反转,反转之后依次判断是否相等,值得注意的是因为mid指向反转后的链表并没有断开,因此判断的结束条件是快指针的next为空。同时要注意只有一个节点的情况,因此反转链表的时候要判断一下head是否为空。
class Solution {
public:
// 反转链表函数
void reverse(ListNode *head)
{
if (head != nullptr)
{
ListNode *prevNode = nullptr;
ListNode *currNode = head;
ListNode *nextNode = head;
while(nextNode != nullptr)
{
nextNode = currNode->next;
currNode->next = prevNode;
prevNode = currNode;
currNode = nextNode;
}
}
}
bool isPalindrome(ListNode* head) {
ListNode *mid = head, *tail = head;
// mid找到中间的节点,tail找到尾部节点
while (tail->next != nullptr)
{
tail = tail->next;
if (tail->next != nullptr)
{
tail = tail->next;
mid = mid->next;
} else
break;
}
// 反转mid后面的链表
reverse(mid->next);
// 开始判断是否回文
while(tail != nullptr)
{
if (head->val != tail->val)
return false;
else
{
head = head->next;
tail = tail->next;
}
}
return true;
}
};
Accepted
- 88/88 cases passed (160 ms)
- Your runtime beats 90.08 % of cpp submissions
- Your memory usage beats 85.66 % of cpp submissions (111.3 MB)