力扣234题,回文链表

力扣234题,回文链表

题目描述

给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false

输入输出样例

在这里插入图片描述

输入:head = [1,2,2,1]
输出:true

在这里插入图片描述

输入:head = [1,2]
输出:false

**进阶:**你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?****进阶:你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

解法一,借用容器


//常规解法,将链表的数据添加到数组中然后判断是否是回文
//时间复杂度 O(n) 空间复杂度 O(n)
bool isPalindrome(ListNode*head)
{
    if(!head)
    {
        return true;
    }

    ListNode *ptemp=head;
    vector<int>nums;
    while(ptemp)
    {
        nums.push_back(ptemp->val);
        ptemp=ptemp->next;
    }

    int length=nums.size();
    int left=0;
    int right=length-1;

    while(left<right)
    {
        if(nums[left]!=nums[right])
        {
            return false;
        }
        left++;
        right--;
    }
    return true;
}

解法二,迭代


ListNode *firstNode;

bool dfsNode(ListNode *&currNode)
{
    //先判断有效性
    if(!currNode)
    {
        return true;
    }

    bool res=dfsNode(currNode->next);

    //递归走到下一个结点
    if(res)
    {
        if(currNode->val==firstNode->val)
        {
            firstNode=firstNode->next;
            return true;
        }
        else
        {
            return false;
        }
    }
    return false;
}


bool dfsNode2(ListNode *currNode)
{
    if(currNode!=nullptr)
    {
        if(!dfsNode2(currNode->next))
        {
            return false;
        }

        if(currNode->val!=firstNode->val)
        {
            return false;
        }
        firstNode=firstNode->next;
    }
    return true;
}

//解法二,使用递归的方法进行求解
bool isPalindrome2(ListNode*head)
{
    firstNode=head;
    return dfsNode(head);
    
}

时间复杂度o(n)

空间复杂度O(n)

解法三,快慢指针+翻转链表


ListNode*reverseList(ListNode*head)
{
    if(head==nullptr||head->next==nullptr)
    {
        return head;
    }
    ListNode *cur=reverseList(head->next);

    head->next->next=head;
    head->next=nullptr;

    return cur;

}

//解法三使用快慢指针的方法,初始化快慢指针均指向起点。但快指针是慢指针移动速度的两倍
bool isPalindrome3(ListNode*head)
{
    if(!head||!head->next)
    {
        return true;
    }

    //初始化快慢指针
    ListNode *fast,*slow;
    fast=head;
    slow=head;

    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
    }

    //当跳出循环便证明slow已经到了中间了
    //借用力扣207题的翻转链表的思想
    ListNode *reverseNode=reverseList(slow);
    slow->next=nullptr;

    //比较两个链表是否为回文串
    while(head&&reverseNode)
    {
        if(head->val!=reverseNode->val)
        {
            return false;
        }
        head=head->next;
        reverseNode=reverseNode->next;
    }
    return true;

}

解法四,合并快慢指针和翻转链表


bool isPalindrome4(ListNode*head)
{
    if(!head||!head->next)
    {
        return true;
    }

    //初始化快慢指针
    ListNode *fast,*slow;
    fast=head;
    slow=head;

    ListNode *cur,*pre;
    pre=nullptr;
    cur=head;
    //边移动边翻转
    while(fast&&fast->next)
    {
        cur=slow;
        slow=slow->next;
        fast=fast->next->next;
        cur->next=pre;
        pre=cur;
    }
    
    //避免偶数
    if(fast)
    {
        slow=slow->next;
    }

        //比较两个链表是否为回文串
    while(cur&&slow)
    {
        if(cur->val!=slow->val)
        {
            return false;
        }
        cur=cur->next;
        slow=slow->next;
    }
    return true;


}

时间复杂度 O(n)
空间复杂度O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值