题目描述:
给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
因为这一题是受到876题求链表中间节点的启发,所以在这里也加一下。
876.链表的中间结点
给你单链表的头结点 head ,请你找出并返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
思路: 设置快慢指针,快指针以2为步长,慢指针以1为步长。因为两者是两倍关系,所以当快指针遍历完成后,慢指针就到达了中间节点。因为节点数分奇偶数,所以循环条件以&&的形式。
代码:
class Solution {
public ListNode middleNode(ListNode head) {
ListNode fast=head;
ListNode slow=head;
while(fast!=null&&fast.next!=null) {
fast=fast.next.next;
slow=slow.next;
}
return slow;
}
}
然后回到234的回文链表这一题。首先按照876题的方法求得中间节点,之后将中间节点后的节点的指向改为相反方向。然后从链表两侧进行遍历比较即可。改变指向的过程分为两种情况,如果链表有奇数个节点,那么按照一般的思想实现代码即可,若链表有偶数个节点,那么最中间的两个节点的判断要进行特殊处理。
代码:
class Solution {
public boolean isPalindrome(ListNode head) {
if(head==null) {
return true;
}
ListNode fast=head;
ListNode slow=head;
while(fast!=null&&fast.next!=null) {
fast=fast.next.next;
slow=slow.next;
}
ListNode cur=slow.next;
while(cur!=null) {
ListNode curNext=cur.next;
cur.next=slow;
slow=cur;
cur=curNext;
}
fast=head;
while(fast.val==slow.val) {
if(slow==fast) {
return true;
}
if(fast.next==slow&&fast.val==slow.val) {
return true;
}
slow=slow.next;
fast=fast.next;
}
return false;
}
}