【LeetCode】234. 回文链表
一、题目内容
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
二、考查内容
双指针、递归、栈、链表反向、快慢针
三、解题思路
思路一:将链表复制到一个数组中,然后用双指针判断这是不是回文(稍微改一下就是:将链表压入栈,然后栈顶元素和链表逐一比较)
思路二:利用计算机在执行函数递归的时候其实是在使用栈的特点,使用递归来进行链表的反向遍历。虽然这种方法对于内存的开销会比思路一差,甚至会比直接将链表每个元素压入栈的方法的内存开销大,但是这种思想还是十分重要的!!
思路三:将链表后半段(快慢针找中点)反向,然后双指针分别从头和尾比较元素值
要注意题目数据与数据结构特点。注意到链表反向其实是可以在原地址做到的,所以这种方法的内存复杂度是O(1),因为也没有循环套循环之类的操作,时间复杂度可以做到O(n)。(其实如果不是题目的进阶要求了复杂度,直接就使用栈了。。。)
四、作答
我的代码
思路三:(比官方还短233 在用例测试时候发现官方把head == NULL的情况也算作是回文链表,单个结点也是回文链表,[1,2,1]之类也算(这种就是,不像用例那样把中间值重复两次))
void reverse(struct ListNode* r)
{
if(r->next == NULL) return;
struct ListNode* p = r->next;
struct ListNode* q = NULL;
r->next = NULL;
while(p != NULL)
{
q = p->next;
p->next = r;
r = p;
p = q;
}
}
bool isPalindrome(struct ListNode* head)
{
if(head == NULL||head->next == NULL) return true;
struct ListNode* pSlow = head;
struct ListNode* pFast = head;
while(pFast->next != NULL && pFast->next->next != NULL)
{
pSlow = pSlow->next;
pFast = pFast->next->next;
}
if(pFast->next != NULL) pFast = pFast->next;
reverse(pSlow);
pSlow = head;
while(pSlow != NULL)
{
if(pSlow->val != pFast->val) return false;
pSlow = pSlow->next;
pFast = pFast->next;
}
return true;
}
错处与修改
无
五、官方或网友解答
思路一:略
思路二:
struct ListNode* frontPointer;
bool recursivelyCheck(struct ListNode* currentNode) {
if (currentNode != NULL) {
if (!recursivelyCheck(currentNode->next)) {
return false;
}
if (currentNode->val != frontPointer->val) {
return false;
}
frontPointer = frontPointer->next;
}
return true;
}
bool isPalindrome(struct ListNode* head) {
frontPointer = head;
return recursivelyCheck(head);
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/palindrome-linked-list/solution/hui-wen-lian-biao-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
思路三:
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode* prev = NULL;
struct ListNode* curr = head;
while (curr != NULL) {
struct ListNode* nextTemp = curr->next;
curr->next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
struct ListNode* endOfFirstHalf(struct ListNode* head) {
struct ListNode* fast = head;
struct ListNode* slow = head;
while (fast->next != NULL && fast->next->next != NULL) {
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
bool isPalindrome(struct ListNode* head) {
if (head == NULL) {
return true;
}
// 找到前半部分链表的尾节点并反转后半部分链表
struct ListNode* firstHalfEnd = endOfFirstHalf(head);
struct ListNode* secondHalfStart = reverseList(firstHalfEnd->next);
// 判断是否回文
struct ListNode* p1 = head;
struct ListNode* p2 = secondHalfStart;
bool result = true;
while (result && p2 != NULL) {
if (p1->val != p2->val) {
result = false;
}
p1 = p1->next;
p2 = p2->next;
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/palindrome-linked-list/solution/hui-wen-lian-biao-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。