题目描述
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
测试样例:
1->2->2->1
返回:true
思路
1.用快慢指针找出中间结点和前驱节点pre
2.如果是奇数,如1->2->3->2->1,中间节点是3,前驱结点是2,我们把pre.next置为null,切一刀分成两个链表1->2,3->2->1。
3.再把3->2->1反转过来:1->2->3,与前端链表比较,循环条件是head != null,我们只需判断1,2是否一样,3则代表公共结点不需判断
4.如果是偶数,同理步骤2,步骤3。
所以无论是奇数个还是偶数个,实现代码都一样
代码实现
import java.util.*;
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class PalindromeList {
public boolean chkPalindrome(ListNode head) {
if(head == null || head.next == null)return true;
//用快慢指针找到中间结点和前驱结点pre
ListNode slow = head;
ListNode fast = head;
ListNode pre = null;
while(fast != null && fast.next != null) {
fast = fast.next.next;
pre = slow;
slow = slow.next;
}
//切一刀分成两个链表
pre.next = null;
slow = reverse(slow);
//进行比较
while(head != null ) {
if(head.val != slow.val)return false;
head = head.next;
slow = slow.next;
}
return true;
}
public ListNode reverse(ListNode head) {
ListNode pre = null;
ListNode curNext = null;
while(head != null) {
curNext = head.next;
head.next = pre;
pre = head;
head = curNext;
}
return pre;
}
}