知识点:
- 快慢指针走法:慢指针每次走一步,快指针每次走两步,以 fast.next != null && fast.next.next != null 为循环终止条件,慢指针最终指向链表中点。区别于 fast != null && fast.next.next != null 为循环终止条件的链表环问题。
错误思路:
根据回文链表的定义想到了要先反转链表并将其保存为新的链表,然后新旧链表从头节点的值比较至链表 1/2 处,期间若有不同则返回false,否则返回true。但是,我却忽略了一旦反转整个链表,链表原有的结构就被破坏了,就算反转前保存了其原始状态也不行,因此才有了以下解法。
正确思路:
解法一:找到链表的中点,然后根据中点将链表的后半部分进行反转,反转完成后,对链表的前后两部分进行比较,以此来判断是否为回文链表。
代码如下:
class Solution {
public boolean isPalindrome(ListNode head) {
// 找链表中点 --> slow
ListNode slow, fast;
slow = fast = head;
while(fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
}
// System.out.println(slow.val);
// 反转后半部分的链表节点
ListNode pre = null;
ListNode cur = slow.next;
while(cur != null) {
ListNode temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
// 将前后两部分链表连接在一起
slow.next = pre;
// 开始判断是否为回文链表
ListNode flag = slow.next;
slow = head;
while(flag != null) {
if(flag.val != slow.val) {
return false;
}
flag = flag.next;
slow = slow.next;
}
return true;
}
}
解法二:将链表转换为数组的方式进行回文链表的判断。
class Solution {
public boolean isPalindrome(ListNode head) {
// 声明要存放链表节点值的集合
List<Integer> list = new ArrayList<>();
// 遍历链表,将其各个节点值存于集合中
ListNode cur = head;
while(cur != null) {
list.add(cur.val);
cur = cur.next;
}
// 以数组的方式进行回文链表的判断
int start = 0;
int end = list.size() - 1;
while(start < end) {
if(list.get(start) != list.get(end)){
return false;
}
start++;
end--;
}
return true;
}
}