题目
Given a singly linked list, determine if it is a palindrome.
Example 1:
Input: 1->2
Output: false
Example 2:
Input: 1->2->2->1
Output: true
Follow up:
Could you do it in O(n) time and O(1) space?
十分钟尝试
我想到的是反转链表,然后比较是否相同,写完代码后,发现不行,因为原来的链表已经被修改了,无法比较。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
ListNode reverseHead=reverseList(head);
ListNode curr=head;
ListNode currReverse=reverseHead;
//如何比较两个链表相等,原来对链表,已经被修改了
while(curr!=null&&currReverse!=null){
if(curr.val!=currReverse.val){
return false;
}
curr=curr.next;
currReverse=currReverse.next;
}
return true;
}
private ListNode reverseList(ListNode head){
ListNode pre=null;
ListNode curr=head;
while(curr!=null){
ListNode tmp=curr.next;
curr.next=pre;
pre=curr;
curr=tmp;
}
//注意返回不是curr,因为curr为空
return pre;
}
}
怎么解决呢?不能单独存储,因为空间复杂度高。我们是否可以反转一半,然后和另外一半进行比较,比如1-2--2-1,我们逆转前半部,判断和后半部分是否相同,这样就可以。再来,我们尝试一下。
我的思路:
1 求出size,因为我需要知道中间节点,也就是反转操作的尾节点。
2 逆转前半部分
3,head往后,curr往后,比较是否相同
但是我感觉应该有优化的地方。第一步求size,应该不需要遍历整个链表,这样效率太低了。尝试一下,指针到达中间,还需要保存下面的节点的指针,因为reverse后就丢失了,里面细节太多,可能还需要考虑奇数偶数。所以参考其他人的方法。
我走两步,你走一步,我到达终点的时候是不是你刚好走了一半?
设置快慢两个指针,代码如下,如果fast为空并且fast.next为空,则slow位于中间位置,我发现无论奇数偶数都没有问题,但是作者对奇数进行了slow.next处理。我暂时不考虑这个情况:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
//找到中间位置指针,利用快慢指针
ListNode fast=head;
ListNode slow=head;
while(fast!=null&&fast.next!=null){
//如果偶数个节点,此时fast为空,如果奇数,正好尾部节点
fast=fast.next.next;
slow=slow.next;
}
ListNode reverseHead=reverseList(slow);
fast=head;
while(reverseHead!=null){
if(fast.val!=reverseHead.val){
return false;
}
fast=fast.next;
reverseHead=reverseHead.next;
}
return true;
}
private ListNode reverseList(ListNode head){
ListNode pre=null;
ListNode curr=head;
while(curr!=null){
ListNode tmp=curr.next;
curr.next=pre;
pre=curr;
curr=tmp;
}
//注意返回不是curr,因为curr为空
return pre;
}
}