思路:其实就是判断反转链表是不是和原链表一样的问题。
我们可以借助反转链表的思路,首先我们先把链表的全部元素正向存储,然后再把链表进行反转。
之后我们再遍历反转之后的链表结点元素是不是和刚刚存储数组里面的元素一致就可以了。一旦有一个不一致的就说明不是。否则就是可以。
这个做法的缺点就是消耗的空间复杂度较大。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
int []arr=new int[100010];
ListNode tmp=head;
int len=0;
while(tmp!=null){
arr[len++]=tmp.val;
tmp=tmp.next;
}
ListNode a1=null;
ListNode a2=head;
while(a2.next!=null){
ListNode tmp1=a2.next;
ListNode tmp2=a2;
a2.next=a1;
a2=tmp1;
a1=tmp2;
}
a2.next=a1;
int i=0;
while(a2!=null){
if(a2.val!=arr[i]){
return false;
}
i++;
a2=a2.next;
}
return true;
}
}
思路二:
快慢指针,这里的快慢指针用来查找链表的中点。快指针每次走2步,慢指针每次走1步。
我们找出来中点之后,把后半段的链表进行反转,然后再把其前半段比较就行了。
有人问,如果链表长度是奇数怎么办?没关系,我们还是一样这样做,只不过,我们在判断前半段和后半段是否相等的时候,忽略中点不计,也就是以后半段的长度为主。因为这样快慢指针出来之后,前半段会多出一个,所以我们以后半段的长度为主。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
if(head==null||head.next==null)
return true;
ListNode nima=new ListNode(-1);
nima.next=head;
ListNode slow=nima;
ListNode fast=nima;
while(fast!=null&&fast.next!=null){//奇数长度和偶数长度区别判断
slow=slow.next;
fast=fast.next.next;
}
fast=slow.next;
slow.next=null;
slow=nima.next;
ListNode tmp1=fast;
ListNode tmp2=null;
while(tmp1.next!=null){
ListNode a1=tmp1.next;
ListNode a2=tmp1;
tmp1.next=tmp2;
tmp1=a1;
tmp2=a2;
}
tmp1.next=tmp2;
while(tmp1!=null){
if(tmp1.val!=slow.val)
return false;
tmp1=tmp1.next;
slow=slow.next;
}
return true;
}
}