题目描述:检查一个链表是否为回文链表。
法一:数组+双指针
将链表的值赋值到数组,采用双指针的方式比较头尾的值。
时间复杂度O(n),空间复杂度O(n)。
class Solution {
public boolean isPalindrome(ListNode head) {
if(head==null||head.next==null)
return true;
ArrayList<Integer> list=new ArrayList<>();
ListNode p=head;
while(p!=null){
list.add(p.val);
p=p.next;
}
int i=0;
int j=list.size()-1;
while(i<j){
if(!list.get(i).equals(list.get(j))){
return false;
}
i++;
j--;
}
return true;
}
}
法二:递归
设置一个全局变量用于存储头指针的值,使用递归递归到尾点。边界条件是头、尾的值不同时返回false。
时间复杂度O(n),空间复杂度O(n)。
class Solution {
private ListNode front;
public boolean isPalindrome(ListNode head) {
front=head;
return reverse(front);
}
private boolean reverse(ListNode head){
if(head!=null){
if(!reverse(head.next)) return false;
if(front.val!=head.val) return false;
front=front.next;
}
return true;
}
}
法三:
1.使用快慢指针,令慢指针指向链表的中心结点,当链表长度为奇数时,中心结点属于前半段链表,当链表长度为偶数时两端链表一般长。
2.反转后半段链表。
3.比较前半段和后半段的值。
时间复杂度O(n),空间复杂度O(1)。
class Solution {
public boolean isPalindrome(ListNode head) {
if(head==null||head.next==null)
return true;
//令慢指针指向中间结点
ListNode slow,fast;
slow=head;
fast=head.next;
while(fast!=null&&fast.next!=null){
fast=fast.next.next;
slow=slow.next;
}
ListNode cur=slow.next;
ListNode pre=null;
ListNode temp;
//反转后半段链表
while(cur!=null){
temp=cur.next;
cur.next=pre;
pre=cur;
cur=temp;
}
cur=pre;
//此时cur为后半段链表反转后的头节点
//比较前半段和后半段链表
while(cur!=null){
if(cur.val!=head.val)
return false;
cur=cur.next;
head=head.next;
}
return true;
}
}