数据结构习题--回文链表
给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false
要求:
时间复杂度为O(n)
空间复杂度为O(1)
方法:反转后半链表
分析
因为要求使用O(1)空间复杂度,否则我们可以直接反转链表在一个一个比较,而因为不能开拓这种空间来存储链表,所以这里我们采取把原来的链表的后半部分反转,再与原来的链表的前半部分进行比较
- 先找到链表的中点
- 判断该链表奇偶,对慢指针进行处理
- 一一比较
代码
java
package LinkList;
public class PalindromeList {
/**
* 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; }
* }
*/
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) {
// 初始快慢指针
ListNode fast = head;
ListNode slow = head;
// 这里采用的是反转后半部分链表的方法,当然也可以反转前面链表,大概流程差不多
// 快指针每次移动两格,慢指针每次一格,当快指针跑到结尾时,慢指针恰好在中间
while (fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
}
// 原来的链表分为奇数和偶数情况
// 当是奇数情况时,最中间那个元素不用判断回文,而慢指针指向最中间那个元素,所以单独往后移动一格慢指针
// 比如:12345 结束循环时,快指针在5,慢指针在3,而我们其实只需要反转45就行
// 对于偶数链表: 1234,结束循环时,快指针在(1234null)中的null,慢指针在3.我们需要反转34
// 所以当快指针不为null时,说明链表是奇数,需要处理慢指针
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 nextNode = null;
ListNode preNode = null;
while (head != null){
nextNode = head.next;
head.next = preNode;
preNode = head;
head = nextNode;
}
return preNode;
}
}
}