1. topic
Please judge whether a linked list is palindrome linked list.
Example 1:
Input: 1->2
Output: false
Example 2:
Input: 1 - > 2 - > 2 - > 1
Output: true
Advance:
Can you use O(n) time complexity and O(1) space complexity to solve this problem?
2. way of thinking
- This question can be regarded as Inverted list and Middle node of linked list Combination.
Define fast and slow two pointers, find the middle node, and reverse the first half of the molecular list in the process of slow pointer movement. When the middle node is found, the values of each node in the two linked lists are compared forward and backward respectively.
- Even nodes are as follows
- At this point, we get the first half of the molecular list with slow as the head pointer and the second half with p2 as the head pointer. Because the middle node is biased to the back, we need to compare the two nodes in the middle (here are 2 and 3 nodes), and then compare them to the two sides in turn until they reach the end of the sub chain.
- Let's look at the odd nodes
- For odd nodes, we can still get the first half of the molecular list with slow as the head pointer and the second half of the molecular list with p2 as the head pointer. At this time, since there is no need to compare the middle nodes pointed to by slow, we only need to start from the first node after slow and the node pointed to by p2 to compare the two sides circularly (here are 2 and 4 nodes).
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: bool isPalindrome(ListNode* head) { if (head == NULL || head->next == NULL) // Null chain or only one node, return true { return true; } else { /* This is the three pointers of the reverse linked list. slow stands for p1 */ ListNode* slow = head; // Slow pointer to first node ListNode * p2 = slow->next; // Second node ListNode * p3 = p2->next; // The third node ListNode* fast = head; // Fast pointer to head node // Odd node fast pointer to the end of the last node // Even node fast pointer to NULL end while(fast && fast->next) { p3 = p2->next; fast = fast->next->next; // Two steps forward p2->next = slow; // Inverted list slow = p2; // Slow pointer one step forward p2 = p3; } head->next = NULL; // Handle the tail nodes of the first half of the child chain // Even node if(!fast) { // Compare whether the two nodes after slow are the same if (slow->val == slow->next->val) { // Start with the third node after slow and the node pointed to p2 and compare to both sides circularly slow = slow->next->next; while(slow) { if (slow->val != p2->val) { return false; } else { slow = slow->next; p2 = p2->next; } } return true; } else { return false; } } // Odd node else { // Start with the first node after slow and the node pointed to by p2 and compare to both sides circularly slow = slow->next; while(slow) { if (slow->val != p2->val) { return false; } else { slow = slow->next; p2 = p2->next; } } return true; } } } };
For more highlights, please pay attention to "seniusen"!