描述:给一个单链表,判断是不是回文。
分析:
- 主要思路是,用两个指针遍历单链表,慢指针一步一个节点,快指针一步两个节点。当快指针到达表尾的时候,慢指针到达表中。(注意奇偶)
ListNode slow = head;
ListNode fast = head;
while (fast.next != null && fast.next.next != null) {
slow = slow.next; // 实际不是这样写的,还要复杂一点
fast = fast.next.next;
}
- 在慢指针遍历前半部分的时候,把前半部分方向倒转,也就是说第三个节点的next指向第二个节点,类推。
ListNode pre = null;
ListNode next = slow.next;
while (fast.next != null && fast.next.next != null) {
pre = slow;
slow = next;
next = next.next;
slow.next = pre;
}
- 当慢指针到达表中的时候,前半部分已经reverse,就可以从表中到两端判断是否回文。
while (next != null) {
if (slow.val != next.val) return false;
slow = slow.next;
next = next.next;
}
return true;
完整实现:
public boolean isPalindrome(ListNode head) {
if (head == null) return true;
ListNode slow = head;
ListNode fast = head;
ListNode pre = null;
ListNode next = slow.next;
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next; // 快指针一步两个节点
pre = slow;
slow = next; // 慢指针一步一个节点
next = next.next;
slow.next = pre; // 调转方向
}
if (fast.next == null) slow = slow.next; // 处理奇数,偶数不用处理
while (next != null) {
if (slow.val != next.val) return false;
slow = slow.next;
next = next.next;
}
return true;
}