请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
最容易想到方法:(超时)
转换成数组然后一个从前遍历、一个从后遍历,直到相遇,但是出现超时问题
快慢指针+头插法建立单链表
-
快慢指针我们很容易求出单链表中居于中间位置的值
-
头插法,可以实现原地单链表逆序,我们只是逆序单链表中间位置之前的数据
public boolean isPalindrome(ListNode head) {
if (head == null || head.next == null) return true;
ListNode slow = head, fast = head;
ListNode pre = head;
//新链表的头================
ListNode newhead = new ListNode(0);
newhead.next = null;
//=========================
while (fast != null && fast.next != null) {
pre = slow;
//====快慢指针==========
slow = slow.next;
fast = fast.next.next;
//======================
//头插法建立单链表
pre.next = newhead.next;
newhead.next = pre;
}
//如果是基数个单链表,上面的while循环结束,我们的slow位于中间位置,需要后移一位
if (fast != null) {
slow = slow.next;
}
//fast节点和newhead头进行比较,注意nehaed是带头节点的
newhead = newhead.next;
while (newhead != null && slow != null) {
if (newhead.val != slow.val) {
return false;
}
newhead = newhead.next;
slow = slow.next;
}
return true;
}
总结
在头插法建立单链表的时候,注意顺序,先快慢指针移动,我们才进行头插法,否则会影响结果,引用类型变换
掌握快慢指针、头插法