剑指 Offer II 027. 回文链表

给定一个链表的 头节点 head 请判断其是否为回文链表。

如果一个链表是回文,那么链表节点序列从前往后看和从后往前看是相同的。

示例 1:

img

1
2
输入: head = [1,2,3,3,2,1]
输出: true

示例 2:

img

1
2
输入: head = [1,2]
输出: false

提示:

  • 链表 L 的长度范围为 [1, 105]
  • 0 <= node.val <= 9

思路1:借助数组,然后判断数组是否回文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 public boolean isPalindrome(ListNode head) {
ArrayList<Integer> list = new ArrayList<>();

ListNode cur = head;

while(cur != null){
list.add(cur.val);
cur = cur.next;
}
return isPalindrome(list,0,list.size()-1);

}
boolean isPalindrome(List<Integer> list,int left,int right){
while(left < right){
if(list.get(left) != list.get(right)){
return false;
}
left++;
right--;
}
return true;
}

思路2:双指针+反转链表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public boolean isPalindrome(ListNode head) {
if(head == null || head.next == null){
return true;
}
//快慢指针
ListNode slow = head;
ListNode fast = head;

//快指针走两步,慢指针走一步,快指针走到链表末尾,慢指针走到链表中心
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
}
//这里需要判断一下链表的奇偶性,因为我们只能比较两条长度相同的链表
if(fast != null){
//fast不为空证明链表长度为奇数,可以画图感受一下
slow = slow.next;
}

ListNode newHead = reverLinkedList(slow);
//这里也可以用slow和fast接受,为了便于理解,使用两个新指针
ListNode cur1 = head;
ListNode cur2 = newHead;
//这里要用反转之后的链表头结点作为判断依据
//因为如果链表为奇数的话,前半段链表会比后半段多一个节点
//会报空指针
while(cur2 != null){
if(cur1.val != cur2.val){
return false;
}
cur1 = cur1.next;
cur2 = cur2.next;
}
return true;

}
ListNode reverLinkedList (ListNode head){
ListNode pre = null;
ListNode cur = head;
ListNode temp = null;
while(cur!=null){
temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
}