题目
代码
法一:将链表转换成数组
class Solution {
public boolean isPalindrome(ListNode head) {
//方法一将链表转换数组,使用双指针判断是否是回文链表
List<Integer> list=new ArrayList<Integer>();
ListNode cur=head;
while(cur!=null){
list.add(cur.val);
cur=cur.next;
}
int left=0,right=list.size()-1;
while(left<right){
if(list.get(left)!=list.get(right)){
return false;
}
left++;
right--;
}
return true;
}
}
时间复杂度:
时间复杂度:O(n),其中 n 指的是链表的元素个数。
第一步: 遍历链表并将值复制到数组中,O(n)。
第二步:双指针判断是否为回文,执行了 O(n/2) 次的判断,即 O(n)。
总的时间复杂度:O(2n) = O(n)。
空间复杂度:O(n)
法二
找到中间节点 快指针两步慢指针一步 中间节点靠前的那个节点(偶数)
反转后半部分链表
遍历两个链表
class Solution {
public boolean isPalindrome(ListNode head) {
if (head == null) {
return true;
}
// 找到前半部分链表的尾节点并反转后半部分链表
ListNode firstHalfEnd = endOfFirstHalf(head);
ListNode secondHalfStart = reverseList(firstHalfEnd.next);
// 判断是否回文
ListNode p1 = head;
ListNode p2 = secondHalfStart;
boolean result = true;
while (result && p2 != null) {
if (p1.val != p2.val) {
result = false;
}
p1 = p1.next;
p2 = p2.next;
}
// 还原链表并返回结果
//firstHalfEnd.next = reverseList(secondHalfStart);
return result;
}
//双指针翻转链表
private ListNode reverseList(ListNode head) {
ListNode pre= null;
ListNode cur = head;
while (cur != null) {
//用到了.next将cur.next临时保存
ListNode temp = cur.next;
cur.next = pre;
//pre和cur各自后移
pre = cur;
cur.next = temp;
}
return pre;
}
//前半部分的链表,找到中间节点
//偶数个节点靠前的那个位置中间节点
private ListNode endOfFirstHalf(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
}
时间复杂度其中O(n)
空间复杂度O(1)