题目描述:
描述 :
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
测试样例:
1->2->2->1
true
链接:点这里
来源:牛客网
解题思路1:
判断链表是不是回文结构 , 只需要两个指针 , 一个从前往后 , 另一个从后往前 , 判断每一对元素是不是相等 ;但是单链表只支持从前往后遍历 , 实现不了从后往前的 ; 由此我们就想怎么才能实现将后半段链表元素从后往前遍历呢?
所以这里可以去实现将链表的后半段节点反转(反转单链表) , 此时上面的想法就可以实现了 , 后半段的反转需要先找到中间节点(利用快慢指针去实现) ;
要实现这个过程还有很多细节需要注意 , 具体看下面给出的代码 .
![](https://img-blog.csdnimg.cn/img_convert/4a29524e26253009442791d02461f92d.png)
代码实现1:
import java.util.*;
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class PalindromeList {
public boolean chkPalindrome(ListNode A) {
// write code here
//空的时候
if(A == null){
return false;
}
//只有一个节点
if(A.next == null){
return true;
}
//先找中间位置
ListNode fast = A;
ListNode slow = A;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
}
//从中间位置往后的反转
ListNode cur = slow.next;
while(cur != null){
ListNode curNext = cur.next;
cur.next = slow;
slow = cur;
cur = curNext;
}
//一个从头走 一个从后走 判断回文
while(A != slow){
if(A.val != slow.val){
return false;
}
if(A.next == slow){
return true;
}
A = A.next;
slow = slow.next;
}
return true;
}
}
解题思路2:
借助赋值空间,因为题目说了链表节点个数不超过900,因此辅助空间大小是固定的,故空间复杂也是O(1);遍历链表,将链表中节点的值域放到数组,检测数组是否为回文结构。
代码实现2:
import java.util.*;
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class PalindromeList {
public boolean chkPalindrome(ListNode A) {
int[] array = new int[900];
ListNode cur = A;
int size = 0;
while (cur != null) {
array[size++] = cur.val;
cur = cur.next;
}
// 判断是否为回文结构
int left = 0;
int right = size - 1;
while (left < right) {
if (array[left] != array[right]) {
return false;
}
left++;
right--;
}
return true;
}
}
提交结果:
![](https://img-blog.csdnimg.cn/img_convert/568f783f17f82ea3124bc325f3d1f531.png)