[链表]–回文链表
题目链接
类似题型 相同题型
题目
请判断一个链表是否为回文链表。
示例
输入: 1->2->2->1
输出: true
输入: 1->2
输出: false
解析
回文链表,关于中间对称,对于链表来说,怎么判断呢?这就想到了之前的反转链表,把链表的后半部分给反转了,然后从两边开始遍历比较就好了。
- 定义双指针寻找中间节点。使用的就是快慢指针了,让 fast 每次走两个节点,slow 每次走一个节点,那么如果节点个数是奇数,fast到达尾结点,slow刚好处于中间;如果节点个数是偶数,fast 到达尾结点下一个也就是 null,slow处于后半部分的开始。所以快慢指针完全适用。
- 反转后半部分链表。不说了不说了;
- 比较前后两部分。让 fast 位于头,slow处于尾,同时开始遍历,如果节点值不相等了,就不是回文链表,相等就继续比较 next,直到两个节点相遇(节点个数是奇数)或者fast.next = slow (节点个数是偶数)两个指针指向的节点值都相等,那肯定就是回文链表了。
代码实现
public class Solution234 {
/**
* Definition for singly-linked list
*/
class ListNode {
int val;
ListNode next;
public ListNode(int val) {
this.val = val;
}
}
/**
* 1.定义双指针寻找中间节点
* 2.反转后半部分链表
* 3.比较前后两部分链表
*/
public boolean isPalindrome(ListNode head) {
if (head == null) return true;
// 定义双指针
ListNode fast = head;
ListNode slow = head;
// 寻找中间节点
// fast 到达尾部时, slow 刚好到达中间节点(奇数)或右边一个中间节点(偶数)
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
// 反转后半部分
ListNode prev = slow;
slow = slow.next;
while (slow != null) {
ListNode slowNext = slow.next;
slow.next = prev;
prev = slow;
slow = slowNext;
}
// 比较前后两部分
fast = head;
slow = prev;
while (fast != slow) {
if (fast.val != slow.val) {
return false;
}
// 偶数情况
if (fast.next == slow) {
return true;
}
fast = fast.next;
slow = slow.next;
}
return true;
}
}
-----------------------------------------------------------------------------有始有终分割线----------------------------------------------------------------------------------