題目信息
請判斷一個鏈表是否爲迴文鏈表。
示例 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;
}
}