判定链表是否是回文
[!Tip]
本节源代码见Github链接🔗
问题描述
判定链表是否是回文(顺读和倒读都是一样的)?
核心思路
参考08-找到链表的中间结点,将链表平均分割成两部分,并将后半段链表逆置,对比两部分链表数据是否相同。包含以下5步:
- 定义两个指向链表头结点的指针slowPtr和fastPtr,以不同的速度向前移动,slowPtr每次移动1个结点,fastPtr每次移动两个结点;
- 当fastPtr移动到末尾时,slowPtr刚好指向中间结点;
- 从slowPtr的后继结点开始,逆置链表;
- 比较前半部分和后半部分的结点数据是否相同,若数据相同,则链表数据是回文;
- 还原后半部分链表数据。
[!Tip] 需要注意链表结点数的奇偶性。若链表结点数是奇数,则要剔除掉中间结点进行比较
实现代码
【👉🏻>>点击展开查看代码】
/**
* 判定链表是否是回文
*
* @param headNode
* @author: Max Solider
* @date: 2022/10/11 22:39
*/
boolean isPalindromeList(NormalListNode headNode) {
if (headNode == null || headNode.getNext() == null || headNode.getNext() == headNode) {
System.out.println("The linked list is palindrome list.");
return true; }
// 先找到中间结点
NormalListNode slowPtr = headNode;
NormalListNode fastPtr = headNode;
while (fastPtr.getNext() != null && fastPtr.getNext().getNext() != null) {
fastPtr = fastPtr.getNext().getNext();
slowPtr = slowPtr.getNext();
}
// 逆置后半部分链表
NormalListNode secondHalf = reverseList(slowPtr.getNext());
NormalListNode firstHalf = headNode;
NormalListNode secondHalfHead = secondHalf;
boolean palindrome = false;
// 因为链表长度可能是奇数,前半部分可能会比后半部分多一个数据,所以用后半部分的长度来遍历
while (secondHalf != null) {
if (secondHalf.getData() != firstHalf.getData()) {
break;
}
secondHalf = secondHalf.getNext();
firstHalf = firstHalf.getNext();
}
if (palindrome) {
System.out.println("The linked list is palindrome list.");
} else {
System.out.println("The lined list is not palindrome list.");
}
// 还原后半部分链表
reverseList(secondHalfHead);
listLength(headNode);
return true;}
/**
* 逆置链表
*
* @author: Max Solider
* @date: 2022/10/11 23:26
* @param headNode
* @return org.example.linkedlist.normal.NormalListNode
*/
NormalListNode reverseList(NormalListNode headNode) {
if (headNode == null || headNode.getNext() == null) {
return headNode;
}
NormalListNode current = headNode;
NormalListNode previous = null;
while (current != null) {
NormalListNode temp = current.getNext();
current.setNext(previous);
previous = current;
current = temp;
}
return previous;
}
时间复杂度
时间复杂度为O(n),用于遍历链表。
空间复杂度
空间复杂度为O(1),用于存储临时变量。