234. 回文链表 快慢指针

牧云@^-^@ 提交于 2019-12-02 05:07:01

题目
请判断一个链表是否为回文链表
时间复杂度O(n)
空间复杂度O(1)

快慢指针

快慢指针非常适合这种有中点的问题,并且在移动快慢指针的过程,将原有的链表拆成了两部分(注意:对原链表进行了操作,若为工程不该这么做,但是题目要求空间复杂度O(1)),然后再往后逐一比较。
注意点:

  1. 头插法
  2. 奇偶情况不同
    在这里插入图片描述
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;
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!