之前我写了两篇关于回文性质的文章。
现在遇到一种特殊的回文实例,即链表的回文性质确定。
给一个单向链表,如何确定其为回文链表?
确定回文的最快方法为找到中间元素,左右开弓,比较对折重叠位置上元素值是否相等。
要解决这个问题,得先找到链表的中间位置,怎么找?
一个方法快慢指针法。
一个指针以单个单个元素向前推进,另一个指针一次前进两个单位(每个元素为一单位)
这样当快指针到达了链表末端,慢指针就在链表的中间位置了;
要注意一点,当链表为偶数,慢指针的位置刚好是链表对折的后半段的开头位置;
而当链表为奇数,慢指针的位置正好是链表的正中间,而该元素不参与值得比较(因为该位置不成对)。
找到中间位置后,便将链表一拆为二,将前半段翻转,与后半段进行相应元素比较。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*///节点详情
class Solution {
public boolean isPalindrome(ListNode head) {
if(head == null||head.next == null)
return true;//空链表与单节点链表为回文链表
ListNode ohalf = head; //慢指针
ListNode half = null; //循环后该节点为,链表前半段最末节点
ListNode speed = head;//快指针
while(speed != null&& speed.next != null)
{
ListNode temp = ohalf;
ohalf = ohalf.next;
speed = speed.next.next;
temp.next = half;
half = temp;//将前半段链表翻转即节点指向转向 在比较后半段是原先方向 而前半段得反行这样才可以一一比较
if(speed!= null && speed.next == null)
{
if(speed.val != head.val)
return false;
}else if(speed!= null && speed.next.next == null)
{
if(speed.next.val != head.val)
return false;
}//这段if语句比较首尾两个元素是否相等可以提前判断 头尾不相等的链表为非回文链表
}
if(speed != null)
ohalf = ohalf.next; //奇数链表 后半段头指针前一一个单位
while(ohalf.next != null && half != null)
{
if(ohalf.val != half.val)
return false;
ohalf = ohalf.next;
half = half.next;
}//前后半段链表元素比较
return true;
}
}
如果你有更好想法或者我有写的不清楚的地方,恳请指出,谢谢!