回文链表
234. 回文链表
给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
示例 1:
输入:head = [1,2,2,1]
输出:true
示例 2:
输入:head = [1,2]
输出:false
提示:
链表中节点数目在范围[1, 105] 内
0 <= Node.val <= 9
进阶:你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
解法1 数组+双指针
class Solution {
public boolean isPalindrome(ListNode head) {
int[] a = new int[100010];
ListNode p = head;
int n = 0;
while (p != null) {
a[n++] = p.val;
p = p.next;
}
for (int i = 0, j = n-1; i < j; i++, j--) {
if (a[i] != a[j]) {
return false;
}
}
return true;
}
}
解法2 链表中间节点+反转链表
class Solution {
public boolean isPalindrome(ListNode head) {
ListNode mid = middleNode(head); //获取中间节点
ListNode head2 = reverseList(mid); //反转后半部分链表
ListNode tmpHead2 = head2;
while (head2 != null) { //判断链表前半段与后半段是否对称
if (head.val != head2.val) {
reverseList(tmpHead2); //恢复链表
return false;
}
head = head.next;
head2 = head2.next;
}
reverseList(tmpHead2);
return true;
}
public ListNode middleNode(ListNode head) { //查找链表中间节点
ListNode fast = head;
ListNode slow = head;
while (fast.next != null) {
fast = fast.next;
if (fast.next != null) {
fast = fast.next;
}
slow = slow.next;
}
return slow;
}
public ListNode reverseList(ListNode head) { //反转链表
ListNode pre = null;
ListNode cur = head;
while (cur != null) {
ListNode nxt = cur.next;
cur.next = pre;
pre = cur;
cur = nxt;
}
return pre;
}
}