对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。
什么是回文:正读,反读都一样的句子,字符串,数字串等
例如:ABCBA,ABBA都是回文。
思想:
- 找到原链表的中间结点
- 中间结点之后的所有结点形成一个新的mid链表;
- 将mid链表反转,形成反转链表;
- 对原链表 和反转链表进行遍历,遍历的次数为反转链表的长度
如果同一位置结点的val值不相等,则就不是回文结构;
如果原链表中所有与反转链表位置相同的结点的val值都相等,则该链表就是回文结构。
具体实现:
- 定义变量
(1)定义原链表长度的一半,halfLen
(2)定义一个变量 cur 表示当前变量;
(3)定义一个变量mid 表示中间结点,
(4)定义一个变量 newMid表示反转链表 - 找原链表的中间结点
(1)求链表的长度,定义一个函数求链表长度length();
(2)求出链表的一半长度,作为循环条件,找到中间结点 - 链表反转
找到中间结点之后将该链表反转,即将mid链表中的所有结点头插到一个新的链表newMid中; - 将原链表 与 反转链表进行比较,只要有val值不等的,肯定不是回文结构,返回false;否则循环继续;
- 比较结束之后,若没有返回false,则肯定就是回文,返回true。
代码实现:
package www.fanfan.com;
/**
* author:kelly_fanfan
*/
public class NowCode_回文 {
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
//回文
//1.先找到中间结点
//2.把中间结点之后的结点链表反转
public class PalindromeList {
public int legth(ListNode A){
ListNode cur = A;
int len = 0;
while(cur != null){
len++;
cur = cur.next;
}
return len;
}
public boolean chkPalindrome(ListNode A){
int halfLen = legth(A)/2;
ListNode cur = A;
ListNode mid = A;
ListNode newMid = null;
for(int i = 0; i < halfLen;i++){
mid = mid.next;
}
while(mid != null){
ListNode next = mid.next;
mid.next = newMid;
newMid = mid;
mid = next;
}
while(newMid != null){
if(cur.val != newMid.val){
return false;
}else{
cur = cur.next;
newMid = newMid.next;
}
}
return true;
}
}
}