链表的回文结构判断(有复杂度要求)

7 篇文章 0 订阅
4 篇文章 0 订阅

题目描述:

对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。

给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。

示例:

1->2->2->1

返回:true

思路分析:

回文结构即是链表关于中心节点对称,如果没有复杂度要求,可以暴力解法将链表转移到数组中进行判断,或者利用前面博客中讲的尾插的思路来反转链表(传送门:(53条消息) 详解反转链表的思路及方法_好运轩的博客-CSDN博客),一一进行对照。既然无法重新创建新的链表,那么可以反转链表的后半段,然后再对照前后半段链表是否满足回文结构。

在这个思路下,首先要寻找链表的中间节点(节点数为奇数情况下),或者是中间节点的后一个节点(节点数为偶数情况下),可以利用前面的博客来完成此步骤(传送门:(53条消息) 快慢指针找单链表的中间节点(有复杂度的限制)_好运轩的博客-CSDN博客)。其次在反转后半部分链表。最后进行比较。

注意:

如果节点数为奇数的情况下,会出现前半段反转后的链表(n/2 -1)的节点数小于后半段链表的节点数(n/2 +1),那么该如何判断是否满足回文结构呢?

这种思路刚好解决的这种情况,虽然后半段链表反转了,但前半段链表的最后一个节点的指针域仍然指向那个原来的中间节点,如图所示:

因此,不需要单独判断该问题

代码实现:

    bool chkPalindrome(ListNode* A) {
        //write code here

        寻找中间节点
        struct ListNode* fast,* slow;
        fast = slow = A;
        while(fast&& fast->next)
        {
            slow = slow->next;
            fast = fast ->next ->next;
        }
        struct ListNode* mid = slow;

        //翻转后半部分链表
        struct ListNode* cur = mid;
        struct ListNode* newHead = NULL;
        while(cur)
        {
            struct ListNode* next =cur ->next;
            cur ->next = newHead;
            newHead = cur;
            cur = next;
        }

        //判断前半部分链表和后半部分链表是否相同
        while(newHead && A)
        {
            if(newHead ->val != A ->val)
                return false;
            else
            {
                newHead = newHead ->next;
                A = A ->next;
            }
        }
        return true;
    }

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值