难度简单563收藏分享切换为英文关注反馈
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
解法一:空间O(N),时间O(N)
/**
* 判断栈是否是回文结构
*
* @param head
* @return
*/
public static boolean isPalindrome(ListNode head) {
if (head == null || head.next == null) {
return true;
}
Deque<ListNode> stack = new LinkedList<>();
ListNode node = head;
while (node != null) {
stack.push(node);
node = node.next;
}
ListNode node1 = head;
while (!stack.isEmpty()) {
if (stack.pop().val != node1.val) {
return false;
}
node1 = node1.next;
}
return true;
}
解法二:
/**
* 节省一半空间,快慢指针先找到中点位置,然后将后半部分压入栈,比对前半部分
*
* @param head
* @return
*/
public static boolean isPalindrome1(ListNode head) {
if (head == null || head.next == null) {
return true;
}
ListNode slow = head;
ListNode fast = head;
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
//找到中点为slow
ListNode node = slow.next;
Deque<ListNode> stack = new LinkedList<>();
while (node != null) {
stack.push(node);
node = node.next;
}
ListNode node1 = head;
while (!stack.isEmpty()) {
if (stack.pop().val != node1.val) {
return false;
}
node1 = node1.next;
}
return true;
}
解法三:最优解,空间复杂度为1
找到链表中点,再把中点后面的链表反转,判断完了再反转回去
public static boolean isPalindrome2(ListNode head) {
if (head == null || head.next == null) {
return true;
}
boolean res = true;
//先用快慢指针找中点位置,偶数找上中点,奇数找正中点
ListNode slow = head;
ListNode fast = head;
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
//最后slow是中点
//后半部分的头部为中点的下一结点
ListNode lastHead = slow.next;
//然后断开
slow.next = null;
//然后反转中点后面的部分
ListNode pre = null;
ListNode next;
while (lastHead != null) {
next = lastHead.next;
lastHead.next = pre;
pre = lastHead;
lastHead = next;
}
//pre是后半部分的头结点
ListNode node = pre;
ListNode node1 = head;
while (node != null) {
if (node.val != node1.val) {
res = false;
break;
}
node = node.next;
node1 = node1.next;
}
//最后力扣没有要求返回原链表所以暂时不反转回去
return res;
}