Leetcode #234 Palindrome Linked List

Given a singly linked list, determine if it is a palindrome.

Follow up:
Could you do it in O(n) time and O(1) space?

用o(n)的space来创建一个反向的链表,也能AC,时间是36ms,代码如下:

class Solution {
public:
    bool isPalindrome(ListNode* head) {

        ListNode* reverse_head = reverseList(head);
        ListNode* original_point = head, * reverse_point = reverse_head;

        while(original_point != NULL){
            if (original_point -> val != reverse_point -> val) return false;
            original_point = original_point -> next;
            reverse_point = reverse_point -> next;
        }
        return true;
    }

    ListNode* reverseList(ListNode* head){

        if(head == NULL) return NULL;

        ListNode* reverse_cur, * reverse_pre;
        ListNode* original_point = head;

        reverse_cur = reverse_pre = new ListNode(original_point -> val);
        original_point = original_point -> next;
        while(original_point != NULL){
            reverse_pre = reverse_cur;
            reverse_cur = new ListNode(original_point -> val);
            reverse_cur -> next = reverse_pre;
            original_point = original_point -> next;
        }

        return reverse_cur;
    }

};

        但这不能满足题目要求,下面是满足空间复杂度要求,且效率更高(24ms)的代码:

class Solution {
public:
    bool isPalindrome(ListNode* head) {

        //if(!head) return true;

        ListNode* fast, * slow, * pre, * cur;

        pre = NULL;
        fast = slow = head;
        bool isOdd = false;

        while (fast != NULL) {
            if(fast->next) {
                fast = fast->next->next;
            }
            else {
                fast = fast->next;
                isOdd = true;
            }

            cur = slow->next;
            slow-> next = pre;
            pre = slow;
            slow = cur;
        }

        if(isOdd) {
            if(pre -> next == NULL) return true;       //链表长度为1
            pre = pre -> next;
        }
        while(slow){
            if(slow -> val != pre -> val)
                return false;
            slow = slow -> next;
            pre = pre -> next;
        }
        return true;
    }
};

        代码中fast指针每次跳两步,而slow指针每次只走一步,这样就保证fast到达链表尾部时,slow刚好走了一半,同时在走的过程中使前半部分链表方向反转。之后就可以从中间向两边发散比较val值了。当然根据链表长度的奇偶性不同,比较时的出发点需要作出相应调整。

        还有一点要注意的是,链表长度为1 的情况,此时,判断 isOdd 为真后,若直接使 pre = pre -> next, 则在下面的val比较时会出现指针异常。所以代码中要加上对pre->next的判断,若为NULL,显然是链表长度为1 的情况,直接返回true。没加这句的代码提交了是会RE的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值