题目描述:判断一个链表是否是回文链表(如何能达到时间复杂度为O(n)的同时空间复杂度为O(1))
解题思路:最初的思路是遍历链表,取出其中的结点值拼成字符串,然后判断字符串是否是回文字符串,如下:
boolean isPalindrome(ListNode head) {
ListNode p = head;
String str = "";
while(p != null){
str += p.val;
p = p.next;
}
return str.equals(new StringBuilder(str).reverse().toString());
}
但该方法显然比较差,占用较多的空间,当输入字符串较大时程序就会出现超时错误。
方法二:另想办法,借鉴“判断链表是否有环”思想利用快慢指针法找到链表中点,然后一个将后半部分就地反转,分别再从头、中点遍历判断是否相等,该方法时间复杂度O(n)、空间复杂度O(1).
然后运用解耦思想,将整个过程分解成三个函数:查找链表中点函数、反转链表函数和比较函数
ListNode reverseList(ListNode head){
ListNode prev = null;//链表原地反转
while(head != null){
ListNode temp = head.next;
head.next = prev;
prev = head;
head = temp;
}
return prev;
}
ListNode findMinddle(ListNode head){
if(head == null || head.next == null)//找到链表中点
return head;
ListNode p = head, q = head;
while(q != null && q.next != null){
p = p.next;
q = q.next.next;
}
return p;
}
boolean isPalindrome(ListNode head) {//比较判断链表是否是回文链表
if(head == null || head.next == null)
return true;
ListNode middle = findMinddle(head);
middle.next = reverseList(middle.next);
ListNode p = head, q = middle.next;
while(p!=null && q!=null && p.val==q.val){
p = p.next;
q = q.next;
}
return q==null;
}