Palindrome:判断一个链表是否是回文链表。
最简单的方式就是构造一个逆序的单链表,然后通过遍历来判断原始链表和反转的链表是否相同。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool isPalindrome(ListNode* head) {
ListNode* reverse = nullptr;
ListNode* node;
ListNode* curr = head;
while(curr != nullptr){
node = new ListNode(curr->val);
node->next = reverse;
reverse = node;
curr = curr->next;
}
return isEqual(head, reverse);
}
private:
bool isEqual(ListNode* head, ListNode* reverse)
{
while(head != nullptr && reverse != nullptr){
if(head->val != reverse->val) return false;
head = head->next;
reverse = reverse->next;
}
return head == nullptr && reverse == nullptr;
}
};
另外一种想法是链表的前一半和后一半是相反的,所以可以将前一半逆序,然后和后一半进行比较。通过栈的先进后出特性可以实现逆序。
如果知道链表长度,则只需要将前一半的节点依次入栈,然后就可以和后面一半进行比较了。如果不知道链表长度,那么可以使用快慢指针定位到链表中间,然后进行比较,另外还要注意长度的奇偶。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool isPalindrome(ListNode* head) {
vector<ListNode*> vecPart;
ListNode* fast = head;
ListNode* slow = head;
while(fast != nullptr && fast->next != nullptr){
vecPart.push_back(slow);
slow = slow->next;
fast = fast->next->next;
}
if(fast != nullptr){//odd number of nodes
slow = slow->next;
}
while(slow != nullptr){
if(slow->val != vecPart.back()->val) return false;
slow = slow->next;
vecPart.pop_back();
}
return true;
}
};
最后,还可以用递归的方法。判断0 ~ n - 1
的链表是否是回文链表,可以先判断第1 ~ n - 2
是否是回文链表,然后再判断第0
个和第n - 1
个是否相等。但是因为无法直接定位到第n - 2
个,所以需要还需要提前计算长度。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool isPalindrome(ListNode* head) {
int len = ListLength(head);
return isPalindrome(head, len).bPalindrome;
}
private:
struct Result
{
bool bPalindrome;
ListNode* corr;
};
int ListLength(ListNode* head)
{
int ret = 0;
while(head != nullptr){
ret++;
head = head->next;
}
return ret;
}
Result isPalindrome(ListNode* head, int length)
{
Result res;
if(length == 0){
res.bPalindrome = true;
res.corr = nullptr;
}
else if(length == 1){//odd number of nodes
res.bPalindrome = true;
res.corr = head->next;
}
else if(length == 2){//even number of nodes
res.bPalindrome = head->val == head->next->val;
res.corr = head->next->next;
return res;
}
else{
res = isPalindrome(head->next, length - 2);
if(res.bPalindrome && head->val == res.corr->val);
else res.bPalindrome = false;
res.corr = res.corr->next;
}
return res;
}
};