题目:
给你一个单链表的头节点 head
,请你判断该链表是否为回文链表。如果是,返回 true
;否则,返回 false
。
解法一:放入数组然后在数组中比较
和回文数组、回文字符串不同,回文链表无法向前遍历,只能往后。所以我们可以将其放入一个可以遍历的容器中,这个容器既可以是栈、ArrayList或者是数组。这里我们用数组来举例:
class Solution {
public boolean isPalindrome(ListNode head) {
ListNode p = head;
int count = 0;
//遍历计算链表长度,否则无法创建数组
while(p != null){
p = p.next;
count++;
}
int[] nums = new int[count];
p = head;
//赋值到数组中
for(int i = 0;i < count;i++){
nums[i] = p.val;
p = p.next;
}
//前后比对
for(int i = 0;i < count/2;i++){
if(nums[i] != nums[count-1-i]){
return false;
}
}
return true;
}
}
解法二:反转后半部分链表
对于回文,我们可以将后半部分进行反转,然后两个指针一个从头开始,一个从中间开始进行遍历比较就可以判断链表是否回文。
class Solution {
public boolean isPalindrome(ListNode head) {
ListNode slow = head;
ListNode fast = head;
//先找到第二段链表的头节点
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
}
ListNode head2 = reserveList(slow);
//开始判断
while(head2 != null){
if(head.val != head2.val){
return false;
}
head = head.next;
head2 = head2.next;
}
return true;
}
//逆序函数
public ListNode reserveList(ListNode head){
ListNode pre = null; //该节点的前一个
ListNode cur = head; //该节点
if(head == null){
return null;
}
while(cur.next != null){
ListNode n = cur.next; //该节点的后一个
cur.next = pre;
pre = cur;
cur = n;
n = n.next;
}
cur.next = pre;
return cur;
}
}