题目信息
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
解法一
class Solution {
public boolean isPalindrome(ListNode head) {
// 链表为空,或者只有一个元素,认为是回文链表
if (head == null || head.next == null) {
return true;
}
List<Integer> list = new ArrayList<>();
ListNode temp = head;
while (temp != null) {
list.add(temp.val);
temp = temp.next;
}
int start = 0, end = list.size() - 1;
while (start <= end) {
if (!list.get(start).equals(list.get(end))) {
return false;
}
start++;
end--;
}
return true;
}
}
解法二
借助链表翻转,以下写法无耻的抄袭了别人的解答,自己写的远不如大神的精简
class Solution {
public boolean isPalindrome(ListNode head) {
// 链表为空,或者只有一个元素,认为是回文链表
if (head == null || head.next == null) {
return true;
}
ListNode slow = head, fast = head;
ListNode pre = head, prepre = null;
while (fast != null && fast.next != null) {
pre = slow; // 用于翻转前半个链表
slow = slow.next; // 走一步
fast = fast.next.next; // 走两步
// 翻转
pre.next = prepre;
prepre = pre;
}
// 说明fast.next == null,说明链表元素个数是奇数,跳过中间结点
// 例 1->2->3->4->5,fast.next.next = 3, 再 fast.next.next = 5
// 例 1->2->3->4,fast.next.next = 3, 再 fast.next.next = null
if (fast != null) {
slow = slow.next;
}
// pre代表翻转后的前半个链表的头结点,slow是后半个链表的头结点
while (pre != null && slow != null) {
if (pre.val != slow.val) {
return false;
}
pre = pre.next;
slow = slow.next;
}
return true;
}
}