请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-linked-list
【解题思路】
1、先使用快慢指针,把链表分割为前半部分和后半部分;
2、原地反转链表的后半部分;
3、比较前半部分与反转后的后半部分,如果链表值相等则为回文链表,不等则不是回文链表;
【提交代码】
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * struct ListNode *next; 6 * }; 7 */ 8 9 10 int isPalindrome(struct ListNode* head){ 11 struct ListNode *fast; 12 struct ListNode *slow; 13 struct ListNode *tmp; 14 struct ListNode *pre; 15 struct ListNode *cur; 16 17 if( head == NULL || head->next == NULL ) 18 return true; 19 20 fast = head; 21 slow = head; 22 23 // 分割链表 24 while( fast != NULL && fast->next != NULL ) 25 { 26 slow = slow->next; 27 fast = fast->next->next; 28 } 29 30 // cur指向链表后半部分的开头,如果是奇数个节点,则指向中心节点; 31 cur = slow;//slow->next; 32 33 //printf("链表的后半部:"); 34 //list_show( cur ); 35 36 // 原地反转后半部链表 37 pre = NULL; 38 while( cur != NULL ) 39 { 40 tmp = cur->next; 41 42 cur->next = pre; 43 44 pre = cur; 45 cur = tmp; 46 } 47 48 //printf("反转后的链表的后半部:"); 49 //list_show( pre ); 50 51 // pre指向后半部链表反转后的开头 52 while( pre != NULL ) 53 { 54 if( head->val != pre->val ) 55 return false; 56 57 pre = pre->next; 58 head = head->next; 59 } 60 61 return true; 62 }