题目:请判断一个链表是否为回文链表。
题解1(栈):
思路:看到回文,首先就想到栈(后进先出)。这种方法思路很简单,就是把前面一段的链表放到栈中,然后将运动指针p指向另一段开头,然后两端不断比较即可。唯一要注意的点是链表长度奇偶时有不同处理。
但是,这种解法效率比较低。
补充:直接将链表全部压栈然后与原链表对比也可以,不用一定要两段进行比较。
Tip:stack.pop()返回的是void,并不能返回元素,要用stack.top()来返回头元素。
/**
* 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:
int getLength(ListNode *head){
int len=0;
while(head){
head=head->next;
len++;
}
return len;
}
bool isPalindrome(ListNode* head) {
if(!head)
return false;
stack<ListNode*> s;
ListNode* p=head;
int len=getLength(head),n;
n=len/2;
for(int i=0;i<n;i++)
{
s.push(p);
p=p->next;
}
if(len%2)
p=p->next;
while(p)
{
if(p->val!=s.top()->val)
return false;
p=p->next;
s.pop();
}
return true;
}
};
题解2:(用数组搭配双指针):
思路:如果是一个数组或者字符串判断回文,可以很容易的利用数组的特性从头尾往中间扫描(但是单链表不能如此)。因此我们可以将链表转移到数组中,然后利用两个指针进行扫描。(我们也可以采用i和n-i+1的关系来从头尾向中间扫描来判断回文。)
//此为官方题解
class Solution {
public:
bool isPalindrome(ListNode* head) {
vector<int> vals;
while (head != nullptr) {
vals.emplace_back(head->val);
head = head->next;
}
for (int i = 0, j = (int)vals.size() - 1; i < j; ++i, --j) {
if (vals[i] != vals[j]) {
return false;
}
}
return true;
}
};