LeetCode——Palindrome Linked List
# 234
Given a singly linked list, determine if it is a palindrome.
Follow up:
Could you do it in O(n) time and O(1) space?
这一题的目的是判断一个单链表是否是回文链表,并且最好是在O(n)时间复杂度和O(1)空间复杂度内完成。第一个思路很简单,就是利用一个栈,将前半段的链表存储到栈中,利用栈的先进后出的性质,与后半段链表一一比较。但这样的方面的空间复杂度是不为O(1)。
- C++
/**
* 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;
stack<int> s;
s.push(head -> val);
ListNode* slow = head;
ListNode* fast = head;
while(fast -> next && fast -> next -> next) {
slow = slow -> next;
fast = fast -> next -> next;
s.push(slow -> val);
}
if(!fast -> next)
s.pop();
while(!s.empty() && slow -> next) {
slow = slow -> next;
int tmp = s.top();
s.pop();
if(tmp != slow -> val)
return false;
}
return true;
}
};
还有一种方法,就是将后半段链表进行重组反转,相当于后半段链表reverse,这个问题前面已经写过了,无论是递归还是迭代都是可以的。
- Java
public class Solution {
public boolean isPalindrome(ListNode head) {
if(head == null || head.next == null) return true;
ListNode fast = head;
ListNode slow = head;
// 寻找中点
while(fast.next != null && fast.next.next != null){
fast = fast.next.next;
slow = slow.next;
}
// 记录第二段链表的第一个节点
ListNode secondHead = slow.next;
ListNode p1 = secondHead;
ListNode p2 = p1.next;
// 将第一段链表的尾巴置空
slow.next = null;
while(p1 != null && p2 != null){
ListNode tmp = p2.next;
p2.next = p1;
p1 = p2;
p2 = tmp;
}
// 将第二段链表的尾巴置空
secondHead.next = null;
// 依次判断
while(p1 != null){
if(head.val != p1.val) return false;
head = head.next;
p1 = p1.next;
}
return true;
}
}