1.leetcode原题链接:. - 力扣(LeetCode)
2.题目描述
给你一个单链表的头节点 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)
空间复杂度解决此题?
3.实现方法
方法一:使用栈
class Solution {
public boolean isPalindrome(ListNode head) {
Stack<ListNode> stack =new Stack<>();
ListNode cur=head;
while(cur!=null){
stack.push(cur);
cur=cur.next;
}
while(head !=null){
if(head.val != stack.pop().val){
return false;
}
head=head.next;
}
return true;
}
}
方法二:使用快慢指针
1.找到链表的中间节点(使用快慢指针,遍历链表,slow 一次走一步,fast 一次走两步。那么当 fast 到达链表的末尾时,slow 就位于中间位置)
2.反转后半部分链表。
3.判断是否回文。
4.恢复链表。
5.返回结果。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
if(head==null || head.next==null){
return true;
}
ListNode n1=head;
ListNode n2=head;
//找到链表的中间节点
while(n2.next!=null && n2.next.next!=null){
n1=n1.next;
n2=n2.next.next;
}
//此时n1为链表的中间节点
//翻转后半部分链表
n2 =n1.next;
n1.next=null;
ListNode n3=null;
while(n2!=null){
n3=n2.next;
n2.next=n1;
n1=n2;
n2=n3;
}
//判断是否为回文数
n3=n1;
n2=head;
boolean result = true;
while(n1!=null && n2 !=null){
if(n1.val !=n2.val){
result =false;
break;
}
n1=n1.next;
n2=n2.next;
}
//恢复链表
n1=n3.next;
n3.next=null;
while(n1 !=null){
n2=n1.next;
n1.next=n3;
n3=n1;
n1=n2;
}
return result;
}
}