请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶: 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
先写一个简单的迭代法对比法(使用额外空间)
/**
* 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 temNode = head;
String s1="",s2="";
while(temNode!=null){
s1+=temNode.val;
s2=temNode.val+s2;
temNode=temNode.next;
}
return s1.equals(s2);
}
}
如果使用空间复杂度为O(1),基本上要找到中间值,但是对于链表不会啊,想不到还是看官方题解吧,使用快慢指针,慢指针一次走一位,快指针一次走两位,当快指针走到末尾时,慢指针正好走到中间位置。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
if(head==null) return true;
ListNode firstOfEndHalf=firstOfHalfNode(head);
ListNode reserverList = reserverListNode(firstOfEndHalf);
while(reserverList!=null){
if(reserverList.val!=head.val) return false;
reserverList=reserverList.next;
head=head.next;
}
return true;
}
//获取后半部分的第一个节点
public ListNode firstOfHalfNode(ListNode head){
ListNode fast=head;
ListNode slow=head;
while(fast.next!=null&&fast.next.next!=null){
slow=slow.next;
fast=fast.next.next;
}
return slow.next;
}
//反转链表
public ListNode reserverListNode(ListNode head){
ListNode prev=null;
ListNode cure=head;
while(cure!=null){
ListNode temNode = cure.next;
cure.next=prev;
prev=cure;
cure=temNode;
}
return prev;
}
}