链表刷题笔记(题解出自灵茶山)

反转链表

cpp 复制代码
class Solution
{
public:
    ListNode* reverseList(ListNode* head)
    {
        ListNode* cur = head;
        ListNode* prv = nullptr;
        while (cur)
        { 
            ListNode* nxt = cur->next;   
            cur->next = prv;
            prv = cur;
            cur = nxt; 
        }
        return prv;
    }
};

反转倒数第n个链表

难点在于怎么找到要反转的头节点的前面一个结点。

可以使用快慢指针。即两个指针初始化为头节点,都从头节点出发。先让快的指针先走n次,如此就跳过了n个结点。慢指针仍在起点不动

然后,慢指针与快指针再同时往后移动,此时就能发现,慢指针指向的位置就是倒数第n个结点的前一个结点。

这里还没有结束,如果链表只有一个结点。那么我们需要创建一个哨兵结点,在前面,这样就可以解决了

cpp 复制代码
class Solution 
{
public:
    ListNode* reverseBetween(ListNode* head, int left, int right)
    {
        ListNode sen(0, head);
        ListNode* p = &sen;
        for (int i = 0; i < left - 1; i++)
        {
            p = p->next;
        }
        ListNode* prv = nullptr;
        ListNode* cur = p->next;
        for (int i = 0; i < right - left + 1; i++)
        { 
            ListNode* nxt = cur->next;
            cur->next = prv;
            prv = cur;
            cur = nxt;
        }
        p->next->next = cur;
        p->next = prv;
        return sen.next;
    }
};

合并链表

cpp 复制代码
class Solution 
{
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) 
    {
        ListNode*tmp1 = list1;
        ListNode*tmp2 = list2;
        ListNode*add = new ListNode(0);
        ListNode*head = add;
        add->next = nullptr;
        while (tmp1 != nullptr && tmp2 != nullptr)
        {
            if (tmp1->val < tmp2->val)
            {
                add->next = tmp1;
                tmp1 = tmp1->next;

            }
            else
            {
                add->next = tmp2;
                tmp2 = tmp2->next;

            }
            add = add->next;
        }
        add->next = tmp1 != nullptr ? tmp1 : tmp2;
        return head->next;
    }
};

环形链表

思路仍为快慢指针。但是判断条件要注意。一个乌龟一个兔子,永远不可能相遇,当它们相遇的时候,就说明这是一个环形链表。

cpp 复制代码
class Solution 
{
public:
    bool hasCycle(ListNode *head) 
    {
        ListNode* fast = head;
        ListNode* slow = head;
        while (fast && fast->next)
        {
            fast = fast->next->next;
            slow = slow->next;
            if (slow == fast)
            { 
                return true;
            }
        }
        return false; 
    }
};

回文链表

就是将反转与寻找链表的中间结点结合起来

cpp 复制代码
class Solution
{
    ListNode* Mid(ListNode* head)
    {
        ListNode* fast = head;
        ListNode* slow = head;
        while (fast && fast->next)
        {
            slow = slow->next;
            fast = fast->next->next;
        }
        return slow;
    }
    ListNode* Reverse(ListNode* head)
    {
        ListNode* pre = nullptr;
        ListNode* cur = head;
        while (cur)
        {
            ListNode* nxt = cur->next;
            cur->next = pre;
            pre = cur;
            cur = nxt;
        }
        return pre;
    }
public:
    bool isPalindrome(ListNode* head)
    {
        ListNode* mid = Mid(head);
        ListNode* head2 = Reverse(mid);
        while (head2)
        {
            if (head->val != head2->val)
                return false;
            head = head->next;
            head2 = head2->next;
        }
        return true;
    }
};

要注意while的判断条件不能是head != head2;

我写的时候错写此条件,会造成错误。

相关推荐
摇滚侠28 分钟前
《RocketMQ 官网》阅读笔记 RocketMQ 订阅 (Subscription)
笔记·rocketmq
冻柠檬飞冰走茶40 分钟前
PTA基础编程题目集 7-15 计算圆周率(C语言实现)
c语言·开发语言·数据结构·算法
m4Rk_1 小时前
【论文阅读】Agent 记忆机制(22):FluxMem——根据对话结构动态选择记忆组织方式
论文阅读·人工智能·学习
风曦Kisaki2 小时前
Kubernetes(K8s)笔记Day03: Pod命名空间,标签,Pod 的调度,污点与容忍度,Pod 常见状态和重启策略,Pod 生命周期
linux·运维·笔记·docker·云原生·容器·kubernetes
六bring个六2 小时前
git使用笔记
笔记·git
砚凝霜2 小时前
软考网络工程师|第 3 章 以太网帧、物理层标准、VLAN 完整备考笔记
网络·笔记
hanlin032 小时前
刷题笔记:力扣第704、977、209题(数组相关)
笔记·算法·leetcode
天国梦2 小时前
英语词汇学习软件深度测评:天学网等三款APP实测对比与选型指南
学习
菜鸟‍2 小时前
【论文学习】Frontiers in Physics 2024 || Cap2Seg:基于文本描述生成的 COVID-19 医学图像分割性能提升方法
人工智能·学习
摇滚侠3 小时前
《RocketMQ 官网》阅读笔记 RocketMQ 消费者组(Consumer Group)消费者(Consumer)
笔记·rocketmq