学习日记【LeetCode】234. 回文链表

【LeetCode】234. 回文链表

一、题目内容

请判断一个链表是否为回文链表。

示例 1:
输入: 1->2
输出: false

示例 2:
输入: 1->2->2->1
输出: true

二、考查内容

双指针、递归、栈、链表反向、快慢针

三、解题思路

思路一:将链表复制到一个数组中,然后用双指针判断这是不是回文(稍微改一下就是:将链表压入栈,然后栈顶元素和链表逐一比较)

思路二:利用计算机在执行函数递归的时候其实是在使用栈的特点,使用递归来进行链表的反向遍历。虽然这种方法对于内存的开销会比思路一差,甚至会比直接将链表每个元素压入栈的方法的内存开销大,但是这种思想还是十分重要的!!

思路三:将链表后半段(快慢针找中点)反向,然后双指针分别从头和尾比较元素值
要注意题目数据与数据结构特点。注意到链表反向其实是可以在原地址做到的,所以这种方法的内存复杂度是O(1),因为也没有循环套循环之类的操作,时间复杂度可以做到O(n)。(其实如果不是题目的进阶要求了复杂度,直接就使用栈了。。。)

四、作答

我的代码

思路三:(比官方还短233 在用例测试时候发现官方把head == NULL的情况也算作是回文链表,单个结点也是回文链表,[1,2,1]之类也算(这种就是,不像用例那样把中间值重复两次))

void reverse(struct ListNode* r)
{
    if(r->next == NULL)    return;
    struct ListNode* p = r->next;
    struct ListNode* q = NULL;
    r->next = NULL;
    while(p != NULL)
    {
        q = p->next;
        p->next = r;
        r = p;
        p = q;
    }
}
bool isPalindrome(struct ListNode* head)
{
    if(head == NULL||head->next == NULL)   return true;
    struct ListNode* pSlow = head;
    struct ListNode* pFast = head;
    while(pFast->next != NULL && pFast->next->next != NULL)
    {
        pSlow = pSlow->next;
        pFast = pFast->next->next;
    }
    if(pFast->next != NULL) pFast = pFast->next;
    reverse(pSlow);
    pSlow = head;
    while(pSlow != NULL)
    {
        if(pSlow->val != pFast->val)  return false;
        pSlow = pSlow->next;
        pFast = pFast->next;
    }
    return true;
}
错处与修改

五、官方或网友解答

思路一:略
思路二:

struct ListNode* frontPointer;

bool recursivelyCheck(struct ListNode* currentNode) {
    if (currentNode != NULL) {
        if (!recursivelyCheck(currentNode->next)) {
            return false;
        }
        if (currentNode->val != frontPointer->val) {
            return false;
        }
        frontPointer = frontPointer->next;
    }
    return true;
}

bool isPalindrome(struct ListNode* head) {
    frontPointer = head;
    return recursivelyCheck(head);
}

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/palindrome-linked-list/solution/hui-wen-lian-biao-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

思路三:

struct ListNode* reverseList(struct ListNode* head) {
    struct ListNode* prev = NULL;
    struct ListNode* curr = head;
    while (curr != NULL) {
        struct ListNode* nextTemp = curr->next;
        curr->next = prev;
        prev = curr;
        curr = nextTemp;
    }
    return prev;
}

struct ListNode* endOfFirstHalf(struct ListNode* head) {
    struct ListNode* fast = head;
    struct ListNode* slow = head;
    while (fast->next != NULL && fast->next->next != NULL) {
        fast = fast->next->next;
        slow = slow->next;
    }
    return slow;
}

bool isPalindrome(struct ListNode* head) {
    if (head == NULL) {
        return true;
    }

    // 找到前半部分链表的尾节点并反转后半部分链表
    struct ListNode* firstHalfEnd = endOfFirstHalf(head);
    struct ListNode* secondHalfStart = reverseList(firstHalfEnd->next);

    // 判断是否回文
    struct ListNode* p1 = head;
    struct ListNode* p2 = secondHalfStart;
    bool result = true;
    while (result && p2 != NULL) {
        if (p1->val != p2->val) {
            result = false;
        }
        p1 = p1->next;
        p2 = p2->next;
    }

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/palindrome-linked-list/solution/hui-wen-lian-biao-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

六、备注

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值