美文网首页
234. Palindrome Linked List (E)

234. Palindrome Linked List (E)

作者: Ysgc | 来源:发表于2020-11-28 00:29 被阅读0次

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

    Example 1:

    Input: 1->2
    Output: false
    Example 2:

    Input: 1->2->2->1
    Output: true
    Follow up:
    Could you do it in O(n) time and O(1) space?


    最直接的方法:

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode() : val(0), next(nullptr) {}
     *     ListNode(int x) : val(x), next(nullptr) {}
     *     ListNode(int x, ListNode *next) : val(x), next(next) {}
     * };
     */
    class Solution {
    public:
        bool isPalindrome(ListNode* head) {
            vector<int> vec;
            ListNode* node = head;
            while (node) {
                vec.push_back(node->val);
                node = node->next;
            }
            
            int length = vec.size();
            for (int i=0; i<length/2; ++i) {
                if (vec[i] != vec[length-i-1]) 
                    return false;
            }
            
            return true;
        }
    };
    

    Runtime: 28 ms, faster than 32.70% of C++ online submissions for Palindrome Linked List.
    Memory Usage: 15.1 MB, less than 27.09% of C++ online submissions for Palindrome Linked List.


    尝试O(1)space解法

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode() : val(0), next(nullptr) {}
     *     ListNode(int x) : val(x), next(nullptr) {}
     *     ListNode(int x, ListNode *next) : val(x), next(next) {}
     * };
     */
    class Solution {
    public:
        bool isPalindrome(ListNode* head) {
            int n = 0;
            ListNode* node = head;
            while (node) {
                ++n;
                if (node->next)
                    node = node->next;
                else
                    break;
            }
            ListNode* tail = node;
            
            cout << "1: " << tail->val << endl;
            
            int i = 0;
            node = head;
            ListNode* prev = new ListNode(0, head);
            while (node) {
                ++i;
                if (i < n/2+1) {
                    prev = prev->next;
                    node = node->next;
                }
                else {
                    ListNode* next_ = node->next;
                    node->next = prev;
                    prev = node;
                    node = next_;
                }
            }
            
            cout << "2: " << endl;
            
            node = head;
            ListNode* node_ = tail;
            for (i=0; i<n/2; ++i) {
                cout << node->val << " - " << node_->val << endl;
                if (node->val != node_->val) {
                    cout << "3: " << node->val << ", false" << endl;
                    delete(prev);
                    return false;
                }
                node = node->next;
                node_ = node_->next;
            }
            
            cout << "3: " << node->val << ", true" << endl;
            
            delete(prev);
            return true;
        }
    };
    

    cout出来结果都是对的,但是LeetCode弹错


    https://leetcode.com/problems/palindrome-linked-list/discuss/487015/addresssanitizer-heap-use-after-free-on-address
    其他人好像也遇到这个情况了

    看答案:
    差不多的意思,但是写的方法巧妙很多了!

    https://zxi.mytechroad.com/blog/list/leetcode-234-palindrome-linked-list/

    class Solution {
    public:
      bool isPalindrome(ListNode* head) {
        ListNode* slow = head;
        ListNode* fast = head;
        while (fast && fast->next) {
          fast = fast->next->next;
          slow = slow->next;
        }
        // if fast != nullptr, list has odd numbers
        if (fast) slow = slow->next;
        slow = reverse(slow);    
        while (slow) {
          if (slow->val != head->val) return false;
          slow = slow->next;
          head = head->next;
        }
        return true;
      }
    private:
      ListNode* reverse(ListNode* head) {
        ListNode* prev = nullptr;
        ListNode* next = nullptr;
        while (head) {
          next = head->next;
          head->next = prev;
          prev = head;
          head = next;
        }
        return prev;
      }
    };
    

    默写了一遍:

    class Solution {
    public:
        bool isPalindrome(ListNode* head) {
            ListNode* slow = head;
            ListNode* fast = head;
            while(fast != nullptr and fast->next != nullptr and fast->next->next != nullptr) {
                slow = slow->next;
                fast = fast->next->next;
            }
            if (fast != nullptr and fast->next != nullptr) {
                slow = slow->next;
            }
            
            ListNode* tail = reverseLL(slow);
            while (head != nullptr and tail != nullptr) {
                if (head->val != tail->val) {
                    return false;
                }
                head = head->next;
                tail = tail->next;
            }
            
            return true;
        }
    private:
        ListNode* reverseLL(ListNode* node) {
            ListNode* prev = nullptr;
            ListNode* curr = node;
            ListNode* next_;
            while (curr) {
                next_ = curr->next;
                curr->next = prev;
                prev = curr;
                curr = next_;
            }
            
            return prev;
        }
    };
    

    Runtime: 24 ms, faster than 71.98% of C++ online submissions for Palindrome Linked List.
    Memory Usage: 14.1 MB, less than 87.04% of C++ online submissions for Palindrome Linked List.

    相关文章

      网友评论

          本文标题:234. Palindrome Linked List (E)

          本文链接:https://www.haomeiwen.com/subject/swsiiktx.html