链表的回文检测
有关链表的回文检测,用到的就是链表操作中常常用到的双指针的方法,找到链表的中点位置,然后依次对比两边的结点。但是在找链表的中点的时候要注意链表的总个数是偶数或者奇数的两种情况。
1.找链表的中点位置,并把中点以前的各个结点的值存入到栈中。
2.针对偶数或者奇数个链表结点,对中点结点做一个小的调整。
3.依次对比栈中结点的值后链表后半部分结点的值是否相等,决定是否是回文结构。
代码实现:
bool isPalindrome(ListNode* head)
{
bool isPalindrome = true;
if(head == NULL)
{
return true;
}
stack<int> s;
//找到链表的中点
ListNode *fast = head;
ListNode *low = head;
while(fast != NULL && fast->next != NULL)
{
s.push(low->val);
fast = fast->next->next;
low = low->next;
}//while
if(fast != NULL)
{
low = low->next;
}
//对比前后两段链表的内容
while(low != NULL)
{
if(low->val != s.top())
{
isPalindrome = false;
break;
}
low = low->next;
s.pop();
}//while
return isPalindrome;
}
这种方法能够实现O(n)的时间复杂度,但是他的空间复杂度同样是O(n).
链表判断回文O(1)空间复杂度
对链表的后半部分逆序,这样就能一次对比前半部分和后半部分的不同了。
bool isPalindrome(ListNode* head)
{
if(head == NULL || head->next == NULL)
return true;
ListNode *fast = head;
ListNode *low = head;
//利用快慢指针找到链表的中点
while(fast != NULL && fast->next != NULL)
{
fast = fast->next->next;
low = low->next;
}
if(fast != NULL)
{
low = low->next;
}
//逆序链表的后半部分
ListNode dummy(-1);
dummy.next = low;
while(low->next != NULL)
{
ListNode *tmp = low->next;
low->next = tmp->next;
tmp->next = dummy.next;
dummy.next = tmp;
}//while
//对比前后两部分
low = dummy.next;
fast = head;
while(low != NULL)
{
if(fast->val != low->val)
return false;
low = low->next;
fast = fast->next;
}
return true;
}