请判断一个链表是否为回文链表。
示例 1:
输入: 1->2 输出: false 示例 2:
输入: 1->2->2->1 输出: true 进阶: 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/palindrome-linked-list
起初遍历链表,获取链表的顺序字符串str,然后调用reverse方法,从而获取字符串的逆序reverseString,返回值为str.equals(reverseString)即可.虽然如此,但是最后提交代码的时候会发现超时了。
所以为了避免超时,我们将整条链表分成两条链表,其中一条链表利用双指针实现链表的逆序,然后同时遍历这两条子链表,判断节点的值是否相同,如果不相同,说明这条链表不是一个回文链表,否则当链表遍历完时,此时直接返回true即可。
对应的代码:
class Solution {
public boolean isPalindrome(ListNode head) {
ListNode pre,cur,newHead;
pre = head;
cur = head;
while(cur != null && cur.next != null && cur.next.next != null){
pre = pre.next;
cur = cur.next.next;
}
newHead = pre.next;
pre.next = null;
newHead = reverse(newHead);
while(newHead != null && head != null){
if(newHead.val != head.val)
return false;
newHead = newHead.next;
head = head.next;
}
return true;
}
public ListNode reverse(ListNode head){
ListNode pre = null,cur = head,tmp;
while(cur != null){
tmp = cur.next;
cur.next = pre;
pre = cur;
cur = tmp;
}
return pre;
}
}
运行结果:
但是代码依旧可以再次优化,通过观察代码,我们发现可以在找到链表的中点的同时,对前一部分的链表进行逆序操作,这样的话就可以直接遍历前一部分和后一部分的链表来判断即可。优化后的代码为:
class Solution {
public boolean isPalindrome(ListNode head) {
ListNode pre,cur,newHead = null,tmp;
pre = head;
cur = head;
while(cur != null && cur.next != null){
cur = cur.next.next;
tmp = pre.next;
pre.next = newHead;
newHead = pre;
pre = tmp;
}
if(cur != null)
pre = pre.next;
while(pre != null && newHead != null){
if(pre.val != newHead.val)
return false;
pre = pre.next;
newHead = newHead.next;
}
return true;
}
}
运行结果:
|