回文链表(双指针法)
LeetCode234
题目描述:
这道题很容易想到一种方法:将整条链表反转和原先的链表进行比较,如果每个节点都一样,说明这个链表是回文链表。但是事先需要对原链表进行复制操作。
下面介绍一种快慢指针的方法,定义一个快指针和一个慢指针,快指针每次走两步,慢指针每次走一步,当快指针走到链表尾部的时候,慢指针就来到了链表的中心。注意链表长度是奇数和偶数存在不同的情况,如下图链表长度为偶数,则快指针为空时,慢指针到达中心位置:
而链表长度为奇数时,快指针的下一个节点为空时,慢指针来到中心位置,但是反转链表要从下一个节点开始。
链表的反转有迭代法和递归法,详见https://blog.csdn.net/Trista__/article/details/116609875?spm=1001.2014.3001.5501
下面上代码:
class Solution {
public boolean isPalindrome(ListNode head) {
if(head == null) return false;
if(head.next == null) return true;
//快慢指针法判断回文链表
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
}
//这个时候slow就是中间的节点
//如果fast没有指向空,说明链表长度是奇数
if (fast != null){
slow = slow.next;
}
//反转后半部分链表,与前面一半比较
ListNode last = reverse(slow);
while (last != null){
if (last.val != head.val) return false;
last = last.next;
head = head.next;
}
return true;
}
//反转链表
public static ListNode reverse(ListNode head){
ListNode pre = null;
ListNode cur = head;
while (cur != null){
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}
}