请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n)
时间复杂度和 O(1)
空间复杂度解决此题?
思路与代码
O(n)
时间复杂度不难,主要是 O(1)
空间复杂度,这要求我们不能借助其他的数据结构来存取节点。
思路
1 找到中间几点
2 反转后半部分链表
3 判断是否回文
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
if (head == null || head.next == null) return true;
// 找到中间节点
ListNode fast = head;
ListNode slow = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
ListNode midNode = slow; // 奇数是中间一个 偶数是中间两个的后一个
ListNode tail = reverse(midNode); // 反转midNode后的链表 并返回翻转后的头节点
while (tail != null) {
if (tail.val != head.val) return false;
tail = tail.next;
head = head.next;
}
return true;
}
// 反转链表是不能用递归,因为递归会导致空间复杂度不是O(1)
public ListNode reverse(ListNode node){
if (node == null) return node;
ListNode lastNode = node.next;
ListNode preNode = node;
node.next = null;
while(lastNode != null){
ListNode tmp = lastNode.next;
lastNode.next = preNode;
preNode = lastNode;
lastNode = tmp;
}
return preNode;
}
}