力扣刷题-热题100题-第24题(c++、python)
234. 回文链表 - 力扣(LeetCode)https://leetcode.cn/problems/palindrome-linked-list/description/?envType=study-plan-v2&envId=top-100-liked
常规法
数组是连续的存储空间,可以根据索引到达任意位置,链表只能一个个的顺着指向访问元素。最常规的方法就是将链表的元素用额外的空间存储到列表里面,看这个列表是否是回文。
//c++
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
bool isPalindrome(ListNode* head)
{
ListNode* a=head;
vector<int> b;
while(a)
{
b.emplace_back(a->val);
a=a->next;
}
for(int i=b.size()-1;i>-1;i--)
{
if(head->val!=b[i]) return false;
head=head->next;
}
return true;
}
};
#python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def isPalindrome(self, head: Optional[ListNode]) -> bool:
a=[]
while head:
a.append(head.val)
head=head.next
return a==a[::-1]
递归法
以一个全局变量记录头指针,然后递归到链表的最后,根据递归的性质不断将头指针的下一个元素与递归的上一层进行比较。
//c++
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
ListNode* frontPointer;
public:
bool a(ListNode* b)
{
if(b!=nullptr)
{
if(!a(b->next)) return false;
if(b->val!=frontPointer->val) return false;
frontPointer=frontPointer->next;
}
return true;
}
bool isPalindrome(ListNode* head)
{
frontPointer=head;
return a(head);
}
};
#python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def isPalindrome(self, head: Optional[ListNode]) -> bool:
self.front_pointer=head
def a(b=head):
if b is not None:
if not a(b.next):
return False
if self.front_pointer.val!=b.val:
return False
self.front_pointer=self.front_pointer.next
return True
return a()
改变链表
不用额外的空间,但又想判断链表,所以一次走一步,一次走两步找到中间位置(挺巧妙的),然后将中间位置往后的链表反转,直接访问元素进行判断,最后要注意恢复链表。
//c++
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* a(ListNode* b)
{
ListNode* pre=nullptr;
while(b)
{
ListNode* nex=b->next;
b->next=pre;
pre=b;
b=nex;
}
return pre;
}
bool isPalindrome(ListNode* head)
{
ListNode* f=head;
ListNode* s=head;
while(f->next&&f->next->next)
{
f=f->next->next;
s=s->next;
}
s=a(s);
f=s;
bool ans=true;
while(head&&s)
{
if(head->val!=s->val) ans=false;
head=head->next;
s=s->next;
}
a(f);
return ans;
}
};
#python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def isPalindrome(self, head: Optional[ListNode]) -> bool:
if not head:
return True
f=head
s=head
while f.next and f.next.next:
f=f.next.next
s=s.next
a=self.reverse(s)
b=a
ans=True
while head and a:
if head.val!=a.val:
ans=False
head=head.next
a=a.next
self.reverse(b)
return ans
def reverse(self,head):
pre=None
c=head
while c:
n=c.next
c.next=pre
pre=c
c=n
return pre