编写一个函数,检查输入的链表是否是回文的。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
三种写法。
1.把链表中的数据放到数组里求解。(这种写法不放代码了)
2.递归求解。定一个指向链表起始节点的指针,然后递归遍历链表。在遍历到最后一个节点的时候和起始指针的值尽心比较。然后令指针指向下一位,返回函数返回上一层。
但函数在进行调用的时候会开辟出栈帧,因此空间复杂度仍为O(n)。
3.将链表从中间分为两部分,反转后一部分链表的节点。然后用双指针进行比较。空间复杂度为O(1).
方法2.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *front = NULL;
bool check(ListNode *cur) {
if(cur == NULL) return true;
if(check(cur -> next) == false) return false;
if(cur -> val != front -> val) return false;
front = front -> next;
return true;
}
bool isPalindrome(ListNode* head) {
front = head;
return check(head);
}
};
方法3.
class Solution {
public:
ListNode *sec = NULL;//存放第二部分链表的头结点。
ListNode* revList(ListNode *cur) {//反转链表
if(cur == NULL) return NULL;
ListNode *tem = revList(cur -> next);
if(tem != NULL) {
tem -> next = cur;
} else {
sec = cur;
}
cur -> next = NULL;
return cur;
}
bool isPalindrome(ListNode* head) {
ListNode *hair = new ListNode();
hair -> next = head;
ListNode *slow = hair, *fast = hair;
while(true) {//快慢指针将链表分为两部分
slow = slow -> next;
if(fast -> next != NULL) fast = fast -> next;
else break;
if(fast -> next != NULL) fast = fast -> next;
else break;
}
ListNode *cur = revList(slow);
while(true) {
if(head == NULL || sec == NULL) break;
if(head -> val != sec -> val) return false;
head = head -> next;
sec = sec -> next;
}
return true;
}
};