题目
关于回文问题的题目在上一篇文章已经描述,读者可以查看上一篇文章,这篇文章详细描述进阶问题。
进阶:如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1).
思路
通过改变链表右半区的结构,使得整个右半区反转,最后指向中间节点。
原链表 | 新链表 |
1->2->3->2->1 | 1->2->3(3指向null)<-2<-1 |
1->2->3->3->2->1 | 1->2->3(3指向null)<-3<-2<-1 |
源码
public class Node{
public int value;
public Node next;
public Node(int data){
this.value=data;
}
}
public boolean isPanlindrome3(Node head){
if(head==null||head.next==null){
return true;
}
Node n1=head;
Node n2=head;
while(n2.next!=null&&cur.next.next!=null){//查找中间节点
n1=n1.next;//n1---中部
n2=n2.next.next;//n2----结尾
}
n2=n1.next//n2---右部份第一个节点
n1.next=null//mid.next----null
Node n3=null;
//对右半区进行反转
while(n2!=null){
n3=n2.next;//n3----保存下一个节点
n2.next=n1;//下一个反转节点
n1=n2;//n1移动
n2=n3;//n2移动
}
n3=n1;//n3----保存最后一个节点
n2=head;//n2----左边第一个节点
boolean res=true;
while(n1!=null&&n2!=null){//检查回文
if(n1.value!=n2.value){
res=false;
break;
}
n1=n1.next;//从右部到中部
n2=n2.next;//从左部到中部
}
n1=n3.next;
n3.next=null;
while(n1!=null){//恢复列表
n2=n1.next;
n1.next=n3;
n3=n1;
n1=n2;
}
return res;
}