题目
请判断一个链表是否为回文链表:
时间复杂度O(n)
空间复杂度O(1)
快慢指针
快慢指针非常适合这种有中点的问题,并且在移动快慢指针的过程,将原有的链表拆成了两部分(注意:对原链表进行了操作,若为工程不该这么做,但是题目要求空间复杂度O(1)),然后再往后逐一比较。
注意点:
- 头插法
- 奇偶情况不同
def isPalindrome(self, head: ListNode) -> bool:
if(not head or not head.next): return True
pre = None # 和 slow 同步
curr = None # 记录新链的头(头插法)
fast = slow = head
while fast and fast.next: # fast不为空的判断一定要有且在前,根据:逻辑短路
pre = slow
slow = slow.next
fast = fast.next.next
pre.next = curr # 让新点插到新链表的头
curr = pre # 让新点成为新链的头
# while结束,此时slow指向中点,而fast指向最后,若fast不为空,则链表长为奇
if fast: slow = slow.next # 若为奇数,则slow在中点,而pre和curr的值是slow前一个结点的值
while curr:
if(curr.val!=slow.val):
return False
curr = curr.next
slow = slow.next
return True
C++:
执行用时 :16 ms, 在所有 cpp 提交中击败了99.31%的用户
内存消耗 :12.4 MB, 在所有 cpp 提交中击败了93.81%的用户
bool isPalindrome(ListNode* head) {
if(!head || !head->next) return true;
ListNode* pre = NULL; // 和 slow 同步
ListNode* curr = NULL; // 记录新链的头(头插法)
ListNode* fast = head;
ListNode* slow = head;
while (fast && fast->next) // fast不为空的判断一定要有且在前,根据:逻辑短路
{ pre = slow;
slow = slow->next;
fast = fast->next->next;
pre->next = curr; // 让新点插到新链表的头
curr = pre; // 让新点成为新链的头
}
// while结束,此时slow指向中点,而fast指向最后,若fast不为空,则链表长为奇
if (fast) slow = slow->next; // 若为奇数,则slow在中点,而pre和curr的值是slow前一个结点的值
while (curr)
{ if(curr->val!=slow->val)
return false;
curr = curr->next;
slow = slow->next;
}
return true;
}
来源:https://blog.csdn.net/qq_41135967/article/details/102719330