请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
解题思路:
使用头插法建立新的链表,即新的节点永远排在头节点的后面,这样将原来的链表反向排列,然后遍历两个链表进行比较,每个节点都相同则返回True;否则,返回False。
这个解法的空间复杂度和时间复杂度都为O(n),在提交记录中排在后面,不是最好的,暂做为一种解法。
Python:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def isPalindrome(self, head: ListNode) -> bool:
#使用头插法建立新链表
first = ListNode(None) #头节点
p = head
while( p ):
new = ListNode(p.val)
new.next = first.next
first.next = new
p = p.next
p = head
while( p ):
if ( first.next.val != p.val):
return False
first = first.next
p = p.next
return True
C++
方法一:
使用头插法创建新的单链表,不满足O(1)的空间复杂度。
class Solution {
public:
bool isPalindrome(ListNode* head) {
if(!head || !head->next)
return true;
ListNode * newlist = new ListNode(-1); //新链表头节点,头插法创建新链表
ListNode *p1 = head, *p2 ;
while(p1){
p2 = new ListNode(p1->val);
p2->next = newlist->next;
newlist->next = p2;
p1 = p1->next;
}
while(head){
if(head->val != newlist->next->val)
return false;
head = head->next;
newlist = newlist->next;
}
return true;
}
};
方法二:
反转链表的后半部分再进行比较。
/**
* 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) {
if(!head || !head->next)
return true;
ListNode* slow = head, *fast = head, *temp = nullptr;
//找中点
while(fast->next && fast->next->next){
slow = slow->next;
fast = fast->next->next;
}
//反转链表后半部分
ListNode * t1 = slow, *t2 = slow->next;
while(t2){
t1 = t2;
t2 = t1->next;
t1->next = temp;
temp = t1;
}
slow->next = temp;
//比较前半部分和后半部分
while(slow->next){
if(head->val != slow->next->val) return false;
head = head->next;
slow = slow->next;
}
return true;
}
};
方法三:使用 栈 实现反向比较。
/**
* 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) {
if(!head || !head->next)
return true;
ListNode *t1 = head;
int count = 0;
while(t1){
++count;
t1 = t1->next;
}
t1 = head;
int i = count / 2, r = count % 2;
stack<int> sk1;
for(; i != 0; --i){
sk1.push(t1->val);
t1 = t1->next;
}
t1 = r==0 ? t1 : t1->next;
while(t1){
if(sk1.top() != t1->val) return false;
sk1.pop();
t1 = t1->next;
}
return true;
}
};