思路:首先找到链表的中心节点,然后从中心节点的下一位开始进行翻转。
然后以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;
}
|