思路:首先找到链表的中心节点,然后从中心节点的下一位开始进行翻转。
然后以rHead!=null作为循环条件,lHead和rHead不断循环下去,不断比较,当出现节点比较不相等时,直接return false即可。
需要解决的问题:
如何找到中心节点?(快慢指针思想)
定义两个指针,一个slow指针,一个fast指针,指向head头结点
其中fast指针一次走两步,慢指针一次走一步,由于快指针较快且是慢指针的两倍,当快指针到终点时或者它的第二步为空时,此时slow恰好是中点。
代码如下:
|
private ListNode middleNode(ListNode head) {
//利用快慢指针获得中心节点
ListNode slow=head;
ListNode fast=head;
while (fast.next!=null&&fast.next.next!=null){
slow=slow.next;
fast=fast.next.next;
}
return slow;
}
|
接着解决翻转问题:
翻转问题比较好解决,首先定义一个newHead为空的节点,把需要翻转的加入,由于链表是顺序的,通过temp保存当前节点的下一位,让当前节点head的下一位指向newHead,newHead再指向head,即可完成指向,最后把temp节点赋值给head。
例如传入的链表为1-》2-》null
此时head=1,temp=2,newHead=null;
首先head.next=newHead 相当于1-》null
newHead=head; newHead的值此时指向1,
最后把head=temp head为2
按照上诉步骤不断循环下去
|
private ListNode reverseList(ListNode head) {
ListNode newHead=null;
while (head!=null){
ListNode tmp=head.next;
head.next=newHead;
newHead=head;
head=tmp;
}
return newHead;
}
|
总体代码:
|
public boolean isPalindrome(ListNode head) {
if (head == null || head.next == null) return true;
if (head.next.next == null) return head.val == head.next.val;
ListNode lHead=head;
ListNode mid=middleNode(head);
ListNode rHead=reverseList(mid.next);
while (rHead!=null){
if(rHead.val!=lHead.val)return false;
rHead = rHead.next;
lHead = lHead.next;
}
return true;
}
private ListNode reverseList(ListNode head) {
ListNode newHead=null;
while (head!=null){
ListNode tmp=head.next;
head.next=newHead;
newHead=head;
head=tmp;
}
return newHead;
}
private ListNode middleNode(ListNode head) {
//利用快慢指针获得中心节点
ListNode slow=head;
ListNode fast=head;
while (fast.next!=null&&fast.next.next!=null){
slow=slow.next;
fast=fast.next.next;
}
return slow;
}
|