回文链表(不带头结点)


一、什么是回文链表?

回文两个字大家一定不陌生,在学习C语言时一定接触过回文。
比如:
一个字符串的逆序
我们定义一个数组里面有这些元素{1,2,3,4,5,4,3,2,1}那么如何判断它是不是回文的呢?

我们通常一般是从头和尾开始进行操作判断,如此便可以知到这个数字是不是回文。

int left = 0, right = strlen(str);
while(left < right)
{
	if(str[left] != str[right])
		break;
	left++;
	right--;
}

这样便可以判断了这个数组是不是回文了。那么链表是不是也可以呢?当然可以。
第一步:遍历整个链表,将链表值复制到数组当中。
第二部:使用双指针法判读是不是为回文。

但这样所使用的时间复杂度为O(n),空间复杂度也为O(n)。这会使我们的空间复杂度不尽人意。那么有没有什么办法可以让它优化一下空间复杂度呢?

二.进阶空间复杂度O(1)

要想空间复杂度为o(1),我们不能再开辟空间了,那么有没有什么办法可以找到链表的中间位置然后在想办法呢?
n/2+n/2=n;

上面的数学公式想必小学就学过吧,如果a走出了两步和b一步相同,那么a和b同时走a会始终落后b一半。因此我们也可以让一个指针走快点一个走慢点也可以达到此效果。

我们可以定义一个快指针

ListNode* quite=head;

一个慢指针

ListNode* slow=head;

每当快指针走两步时慢指针走一步

while(quite!=NULL&&quite->next!=NULL)
    {
        quite=quite->next->next;
        slow=slow->next;
    }

裁判测试样例就不给了,接下来请看函数:

bool isPalindrome(ListNode* head)
{
 ListNode* quite=head;//快指针
 ListNode* slow=head;//慢指针
 while(quite!=NULL&&quite->next!=NULL)
 {
     quite=quite->next->next;//快指针走两步慢指针走一步
     slow=slow->next;
 }
 ListNode* node=reverseList(slow);
 ListNode* L=head;
 while(L!=NULL&&node!=NULL)
 {
     if(node->val!=L->val)
         return false;
     node=node->next;
     L=L->next;
 }
 return true;
}
ListNode* reverseList(ListNode* head)
{
 ListNode* List=head;
 ListNode* sed=head;
 ListNode* L=NULL;
 while(List!=NULL)
 {
     sed=List->next;
     List->next=L;
     L=List;
     List=sed;
 }
 return L;
}
  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值