题目详情
给你一个单链表的头节点 head
,请你判断该链表是否为回文链表。如果是,返回 true
;否则,返回 false
。
示例 1:
输入:head = [1,2,2,1]
输出:true
示例 2:
输入:head = [1,2]
输出:false
Java代码(使用栈)
public boolean isPalindrome(ListNode head) {
ListNode temp = head;
Stack<Integer> stack = new Stack();
//把链表节点的值存放到栈中
while (temp != null) {
stack.push(temp.val);
temp = temp.next;
}
//然后再出栈
while (head != null) {
if (head.val != stack.pop()) {
return false;
}
head = head.next;
}
return true;
}
总结
利用栈的先进后出的特点,先复制一个头节点,然后将链表中所有的值存到栈中,然后再出栈和之前的链表比较,如果相同那么就是回文。
Java代码(快慢指针)
public boolean isPalindrome(ListNode head) {
ListNode fast = head, slow = head;
//通过快慢指针找到中点
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
//如果fast不为空,说明链表的长度是奇数个
if (fast != null) {
slow = slow.next;
}
//反转后半部分链表
slow = reverse(slow);
fast = head;
while (slow != null) {
//然后比较,判断节点值是否相等
if (fast.val != slow.val)
return false;
fast = fast.next;
slow = slow.next;
}
return true;
}
//反转链表
public ListNode reverse(ListNode head) {
ListNode prev = null;
while (head != null) {
ListNode next = head.next;
head.next = prev;
prev = head;
head = next;
}
return prev;
}
总结
先通过快慢指针找到链表的中点,快指针一次走两步,慢指针一次走一步。这里要注意,如果fast != null那么说明fast.next = null,就说明fast在最后一个节点,并且链表的长度是奇数,这时就需要将slow节点向前移动一步,因为在后续比较中需要从中心节点的下一个节点出发,而如果链表是偶数节点,就不需要考虑这个问题。找到中心节点之后,下一步需要反转后半段节点,可以参考链表反转,这样前段链表和后段链表就是一样的,这时再将头节点赋值给fast,来比较前段和后端,如果一样那么就是回文