最近在刷leetcode的题目,遇到了一个题目,百思不得其解,后来终于明白,因此写篇博客记录一下。
首先题目是这样的:
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?
即给定一个链表,判断链表是否是回环链表。链表的每个节点都存有一个值,如-1 > 1 >1 >-1,即为回文链表。难点在于时间复杂度为O(n),空间复杂度为O(1).
解题思路如下:
1 首先用一个快指针,一个慢指针来遍历链表。快指针每次走两步,慢指针每次走一步。等到快指针遍历完链表,慢指针就正好停留在链表的中央。
2 将链表的后半部分进行反转。
3 将链表的前半部分与后半部分逐个比对。若都相同,则为回文链表,否则不是。
链表遍历的时间复杂度大约为 n/2。反转的时间复杂度为n/2。逐个比对的复杂度为n/2,所以总体的时间复杂度为O(n).而其中用于暂存的节点只有两个。因此空间复杂度为O(1)。
代码如下
`
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode * reverse( struct ListNode * head )
{
struct ListNode * p = head ;
struct ListNode *