labuladong刷题笔记一(单链表)

目录

一、单链表

1.单链表的六大解题套路,你都见过么? (快慢指针)

(1)21. 合并两个有序链表 

(2)23. 合并K个升序链表

(3)19. 删除链表的倒数第 N 个结点

(4)876. 链表的中间结点

(5)141. 环形链表 

(6)160. 相交链表 

(7)83. 删除排序链表中的重复元素 

2.递归反转链表:如何拆解复杂问题 

(1)206. 反转链表(递归)

(2)92. 反转一部分链表 (递归)

3.递归思维:k 个一组反转链表 

(1)25. K 个一组翻转链表 (迭代)

4.如何高效判断回文单链表?  (快慢指针+左右指针)

(1)234. 回文链表 


一、单链表

1.单链表的六大解题套路,你都见过么? (快慢指针)

        p->next=p1:表示节点p的下一个节点是p1

        p=p->next:表示向前移动,修改指针p的位置,把p指向原来的下一个节点。

(1)21. 合并两个有序链表 

(2)23. 合并K个升序链表

        优先队列

(3)19. 删除链表的倒数第 N 个

        快慢指针

(4)876. 链表的中间结点

        快慢指针

(5)141. 环形链表 

        快慢指针

(6)160. 相交链表 

注意这段代码:p1永远都不会是nullptr

if(p1->next)
{
    p1=p1->next;
}
else{
    p1=headB;
}

(7)83. 删除排序链表中的重复元素 

        注意最后slowNode->next=nullptr;

        返回head即可。

2.递归反转链表:如何拆解复杂问题 

(1)206. 反转链表(递归)

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

(2)92. 反转一部分链表 (递归)

    struct ListNode {
        int val;
        ListNode *next;
        ListNode() : val(0), next(nullptr) {}
        ListNode(int x) : val(x), next(nullptr) {}
        ListNode(int x, ListNode *next) : val(x), next(next) {}
    };

    ListNode* reverseBetween(ListNode* head, int left, int right) {
        if(left==1)
        {
            return reverseN(head,right);
        }
        head->next=reverseBetween(head->next,left-1,right-1);
        return head;
    }
    //反转前n个结点
    ListNode* successor=nullptr;
    ListNode* reverseN(ListNode* head,int n)
    {
        if(head==nullptr)
        {
            return nullptr;
        }
        if(n==1||head->next==nullptr)
        {
            successor=head->next;
            return head;
        }
        ListNode* last=reverseN(head->next,n-1);
        head->next->next=head;
        head->next=successor;
        return last;
    }

3.递归思维:k 个一组反转链表 

(1)25. K 个一组翻转链表 (迭代)

class Solution {
public:
    int i=0;

    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode *a = head , *b = head ;
        ListNode *myNode=new ListNode(-1);
        ListNode *p=myNode;
        if(!head||!head->next)
        {
            return head;
        }

        while(i < k && b)
        {
            b=b->next;
            ++i;
            if(i==k)
            {
                myNode->next = reverse(a,b);
                for(int j=0;j<k;j++)
                {
                    cout<<myNode->next->val<<endl;
                    myNode=myNode->next;
                }
                a=b;
                i=0;
            }
            else if(b==nullptr)
            {
                myNode->next=a;
            }
        }
        return p->next;

    }

    //反转a与b之间的结点[a,b]
    ListNode* reverse(ListNode* a,ListNode* b)
    {
        ListNode *currentNode=a,
                *lastNode=nullptr,
                *nextNode=nullptr;
        while(currentNode!=b)
        {
            nextNode=currentNode->next;
            currentNode->next=lastNode;
            lastNode=currentNode;
            currentNode=nextNode;
        }
        cout<<"lastnode:"<<lastNode->val<<endl;
        return lastNode;
    }
};

4.如何高效判断回文单链表?  (快慢指针+左右指针)

(1)234. 回文链表 

        (单链表不能倒序遍历)找到链表中心点,将后半部分反转,然后对比。

        快慢指针+左右指针。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烫青菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值