Leetcode 第234题 回文链表 C++解法

一开始看到下面的提示,我就先考虑了下思路。
最简单思路,把链表复制到数组里面。主要花在了空间复杂度上。但空间复杂度高。
如果要求空间复杂度常数,想到的就是反转后半部分链表。但是又觉得是不是太麻烦。对了下答案,还真是这中思路。
唯一思路没通的是递归解法。
1、最简单思路

class Solution {
public:
    bool isPalindrome(ListNode* head) {
        vector<int> p;
        int i=-1,j=0;
        while(head!=nullptr)
        {
            p.push_back(head->val);
            head=head->next;
            i++;
        }
        while(j<i)
        {
            if(p[i--]!=p[j++])
            return false;
        }
        return true;
    }
};

2、反转后半部分链表的做法,按我的思路最少需要三遍遍历,第一遍求长度,第二遍进行到n/2处开始反转,第三遍才是对比是否回文。
但看了答案解法,发现只要两遍就够了,第一遍长度可以不用求的,直接用快慢指针求到中间位置。直接开始反转,还是太嫩了,那就直接上快慢指针解法。

class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if(head==nullptr||head->next==nullptr)
        return true;
        ListNode *fast=head,*slow=head,*halfhead=nullptr;
        while(!(fast==nullptr||fast->next==nullptr))
        {
            fast=fast->next->next;
            slow=slow->next;
        }
        //我这里是想最后循环中止条件简单点,所以让奇数的情况从n/2+2开始。
        if(fast!=nullptr)
            slow=slow->next;
        fast=slow->next;
        slow->next=nullptr;
        while(fast!=nullptr)
        {
            halfhead=fast;
            fast=fast->next;
            halfhead->next=slow;
            slow=halfhead;
        }
        while(slow!=nullptr)
        {
            if(head->val!=slow->val)
                return false;
            head=head->next;
            slow=slow->next;
        }
        return true;
    }
};

递归解法。递归解法关键在于边界条件和递归时机。
之前我想不明白,是因为我把left也放在递归函数里,这样自然无法解答。实际上他俩一个是退一个是进,是没法放在一个递归里,所以只能把left放在函数体外。惭愧的是这个关键点是看了答案才想出来的。

class Solution {
public:
    ListNode *left;

    bool issame(ListNode *right)
    {
        if(right==nullptr)
        return true;
        bool res=issame(right->next);
        bool now=(left->val==right->val);
        left=left->next;
        return res&&now;
    }
    bool isPalindrome(ListNode* head) {
        left=head;
        return issame(head);       
    }
};

第一遍递归有些变量没有必要,逐渐优化为下面

class Solution {
public:
    ListNode *left;

    bool issame(ListNode *right)
    {
        if(right==nullptr)
        return true;
        if(!issame(right->next))
        return false;
        if(left->val!=right->val)
        return false;
        left=left->next;
        return true;
    }
    bool isPalindrome(ListNode* head) {
        left=head;
        return issame(head);       
    }
};
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值