牛客101:链表

目录

一、反转链表

二、链表内指定区间反转

三、链表中的节点每k个一组翻转

四、合并两个排序的链表

五、合并k个已排序的链表

六、判断链表中是否有环

七、链表中环的入口结点

八、链表中倒数最后k个结点

九、删除链表的倒数第n个节点

十、两个链表的第一个公共结点

[十一、链表相加 II](#十一、链表相加 II)

十二、单链表的排序

十三、判断一个链表是否为回文结构

十四、链表的奇偶重排

十五、删除有序链表中重复的元素

十六、删除有序链表中重复的元素II


一、反转链表

反转链表_牛客题霸_牛客网

法一:双指针定位(必须掌握)

创建prev和cur的Node,prev先设置为nullptr,cur设置为head,先存一个t=cur->next(不然往后更新就找不到了),然后修改cur->next为prev,然后prev更新为cur,cur更新为存的t。最后返回prev,画个图很明了。

cpp 复制代码
    ListNode* ReverseList(ListNode* head) {
        ListNode* prev=nullptr,*cur=head;

        while(cur!=nullptr)
        {
            ListNode*tmp=cur->next;
            cur->next=prev;
            prev=cur;
            cur=tmp;
        }
        return prev;
    }

法二:递归

如果head是空直接返回

递归处理,递归退出条件是找到最后一个节点

每层处理的子问题就是让我此刻的head->next的箭头反转,并且head->next箭头也反转,此时因为还未到达上一层递归调用,先指向nullptr,这一步也是为了修改原始头结点的下一个为nullptr

cpp 复制代码
    ListNode* ReverseList(ListNode* head) {
        if(!head||!head->next)return head;
        //找到最后一个节点
        ListNode*newnode=ReverseList(head->next);

        //处理每个子问题
        head->next->next=head;
        head->next=nullptr;
        
        //最后的这个节点作为头返回
        return newnode;
    }

二、链表内指定区间反转

链表内指定区间反转_牛客题霸_牛客网

单链表逆转往往涉及四个节点问题,可以先遍历,找到要逆转的起点,然后重复以下操作n-m次即可,每次更新后,cur恰好变成了我们想要的逆转那个节点,重复操作

1.t=cur->next; 存cur->next,此时t是我们要逆转它的方向的节点

2.存好cur->next后修改cur->next=t->next;让cur连接到下次的"t"

3.然后t->next=pre->next; prev->next存的是上次的"t"将此刻的t->next=上次的"t"(prev->next)

4.prev->next=t; 更新prev->next(存的是每次逆转的那个节点)

既然我们需要prev这个节点,那么我们当我们的原始链表头结点需要操作的时候,就需要一个虚拟头结点

cpp 复制代码
    ListNode* reverseBetween(ListNode* head, int m, int n) {
        ListNode* newhead=new ListNode(0);
        newhead->next=head;

        ListNode*prev=newhead,*cur=head;
        for(int i=1;i<m;++i)
        {
            prev=cur;
            cur=cur->next;
        }

        //循环操作n-m次,可以举个特例n=m的时候就不需要逆转
        for(int i=m;i<n;++i)
        {
            ListNode*t=cur->next;
            cur->next=t->next;
            t->next=prev->next;
            prev->next=t;
        }
        return newhead->next;
    }

三、链表中的节点每k个一组翻转

链表中的节点每k个一组翻转_牛客题霸_牛客网

可以提前设定一个Node(tail)从head开始往后走k步,确定逆转的终点,如果还没到k,tail就到末尾了,那么直接返回head就行,表示不用反转。

创建prev和cur的Node,prev先设置为nullptr,cur设置为head,存一个t=cur->next,然后修改cur->next为prev,然后prev更新为cur,cur更新为存的t。当cur=tail终止这个循环

最后我们让head->next指向以tail为头节点的递归结果即可。注意最后返回prev,画画图就明了了。

cpp 复制代码
    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode*tail=head;
        //找到前k的节点后的一个节点
        //该节点既可以用在这层当作结束标志
        //也可以作为下一层的开始节点
        for(int i=0;i<k;++i)
        {
            //先判断!
            if(tail==nullptr)return head;
            tail=tail->next;
        }
        ListNode*prev=nullptr,*cur=head;
        while(cur!=tail)
        {
            //存一下下个节点
            ListNode*tmp=cur->next;
            //逆转
            cur->next=prev;
            //更新
            prev=cur;
            cur=tmp;
        }
        head->next=reverseKGroup(tail,k);
        return prev;
    }

四、合并两个排序的链表

合并两个排序的链表_牛客题霸_牛客网

很简单,因为单调性,所以双指针

cpp 复制代码
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
        //虚拟头结点
        ListNode*newhead=new ListNode(-1);
        ListNode*tail=newhead;
        ListNode*cur1=pHead1,*cur2=pHead2;
        while(cur1&&cur2)
        {
            if(cur1->val<cur2->val)
            {   
                tail->next=cur1;
                cur1=cur1->next;
            }
            else 
            {
                tail->next=cur2;
                cur2=cur2->next;
            }
            tail=tail->next;
        }
        if(cur1)tail->next=cur1;
        else tail->next=cur2;
        return newhead->next;
    }

五、合并k个已排序的链表

合并k个已排序的链表_牛客题霸_牛客网

先思考暴力思路是怎样的:因为之前我们写过一道题叫合并两个升序链表。那么我们可以先合并前两个,然后再让这个合并的链表跟第三个合并,然后再依次这样合并下去就能完成。这其实很有一股递归的味道。

法一:优先级队列,使得操作很简单

cpp 复制代码
class Solution {
public:
    struct cmp
    {
        bool operator()(ListNode* l1,ListNode* l2)
        {
            return l1->val > l2->val;
        }
    };
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        //创建小根堆(greater)
        priority_queue<ListNode*,vector<ListNode*>,cmp> heap;
        //放头节点
        for(auto l:lists)
            if(l)heap.push(l);//可能会有空数组
        ListNode* ret=new ListNode(0),*tail=ret;
        //比较各个数组中哪个更小,添加到链表
        while(!heap.empty())
        {
            ListNode*t=heap.top();
            heap.pop();
            tail->next=t;
            tail=tail->next;
            //让插入链表的那个节点下一个节点继续入小根堆
            if(t->next)heap.push(t->next);
        }
        tail=ret->next;
        delete ret;
        return tail;
    }
};

法二:分治

其实很容易想到分治,将数组无限缩小,缩小到只有两个,处理这两个(根据快排归并排序的思路),但是怎么找到每段的头的位置,我去突然发现这里是数组,可以直接找了。

cpp 复制代码
class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        return mergeSort(lists,0,lists.size()-1);
    }
    ListNode* mergeSort(vector<ListNode*>&lists,int left,int right)
    {
        //边界处理
        if(left>right)return nullptr;
        if(left==right)return lists[left];

        //分治
        int mid=(left+right)>>1;
        ListNode* l=mergeSort(lists,left,mid);
        ListNode* r=mergeSort(lists,mid+1,right);

        //合并
        return mergeTwoList(l,r);
    }
    ListNode* mergeTwoList(ListNode*list1,ListNode*List2)
    {
        if(list1==nullptr)return List2;
        if(List2==nullptr)return list1;

        ListNode*cur1=list1,*cur2=List2;
        ListNode* head=new ListNode(0),*tail=head;
        while(cur1&&cur2)
        {
            if(cur1->val<=cur2->val)
            {
                tail->next=cur1;
                cur1=cur1->next;
            }
            else
            {
                tail->next=cur2;
                cur2=cur2->next;
            }
            tail=tail->next;
        }
        //没有弄完的直接连接就行,后边都是串起来的
        if(cur1)tail->next=cur1;
        if(cur2)tail->next=cur2;
        tail=head->next;
        delete head;
        return tail;
    }
};

六、判断链表中是否有环

判断链表中是否有环_牛客题霸_牛客网

判环的经典思路就是快慢指针

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

七、链表中环的入口结点

链表中环的入口结点_牛客题霸_牛客网

cpp 复制代码
class Solution {
public:
    ListNode* hasCycle(ListNode *head) {
        ListNode*fast=head,*slow=head;
        while(fast&&fast->next)
        {
            fast=fast->next->next;
            slow=slow->next;
            if(fast==slow)return slow;
        }
        return nullptr;
    }
    ListNode* EntryNodeOfLoop(ListNode* pHead) {
        ListNode*cur1=hasCycle(pHead);
        if(cur1==nullptr)return nullptr;

        ListNode*cur2=pHead;
        while(cur1!=cur2)
        {
            cur1=cur1->next;
            cur2=cur2->next;
        }
        return cur1;
    }
};

八、链表中倒数最后k个结点

链表中倒数最后k个结点_牛客题霸_牛客网

第一眼思路就是先遍历链表看有多少个结点,n,然后再次遍历,遍历到第n-k+1个结点,返回这个结点。其实就是官方解答的方法二

cpp 复制代码
    ListNode* FindKthToTail(ListNode* pHead, int k) {
        ListNode*cur=pHead;
        int n=0;
        while(cur)
        {
            ++n;
            cur=cur->next;
        }
        cur=pHead;
        int times=n-k;
        if(times<0)return nullptr;
        while(times--)
        {
            cur=cur->next;
        }
        return cur;
    }

官方题解是快慢指针的思想,先让fast走k步,然后再一起走,fast=nullptr的时候slow到末尾就是k个结点,

cpp 复制代码
class Solution {
public:
    ListNode* FindKthToTail(ListNode* pHead, int k) {
        ListNode* fast = pHead; 
        ListNode* slow = pHead;
        //快指针先行k步
        for(int i = 0; i < k; i++){  
            if(fast != NULL)
                fast = fast->next;
            //达不到k步说明链表过短,没有倒数k
            else 
                return slow = NULL;//这种方式是先将NULL赋值给slow再返回slow
        }
        //快慢指针同步,快指针先到底,慢指针指向倒数第k个
        while(fast != NULL){ 
            fast = fast->next;
            slow = slow->next;
        }
        return slow;
    }
};

九、删除链表的倒数第n个节点

删除链表的倒数第n个节点_牛客题霸_牛客网

还是找倒数第n个节点的问题,那么思路和上一题大差不差。

先用快慢指针写,因为要删除这个值,所以我们存一下slow前面的一个节点等会删掉slow

cpp 复制代码
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode*fast=head,*slow=fast;
        while(n--)
        {
            if(fast)fast=fast->next;
            else return nullptr;
        }
        ListNode*newhead=new ListNode(-1),*prev=newhead;
        newhead->next=head;
        while(fast)
        {
            fast=fast->next;
            slow=slow->next;
            prev=prev->next;
        }
        prev->next=slow->next;
        delete slow;
        prev=newhead->next;
        delete newhead;
        return prev;
    }

再用先找总结点个数的方法

cpp 复制代码
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        //计算节点总个数
        ListNode*cur=head;
        int count=0;
        while(cur)
        {
            ++count;
            cur=cur->next;
        }
        int times=count-n;
        if(times<0)return nullptr;

        //创建虚拟头结点,cur从头开始
        ListNode*newhead=new ListNode(-1),*prev=newhead;
        newhead->next=head;
        cur=head;

        while(times--)
        {
            cur=cur->next;
            prev=prev->next;
        }

        prev->next=cur->next;
        delete cur;
        prev=newhead->next;
        delete newhead;
        return prev;
    }

十、两个链表的第一个公共结点

两个链表的第一个公共结点_牛客题霸_牛客网

熟悉的题目,第一次见是在抖y上刷到,后来在别的平台写了一次,后面又在笔试训练的时候刷到。

cpp 复制代码
class Solution {
  public:
    ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2) {
        if (!pHead1 || !pHead2) return nullptr;
        ListNode*cur1=pHead1,*cur2=pHead2;
        while(cur1!=cur2){
            cur1=cur1?cur1->next:pHead2;
            cur2=cur2?cur2->next:pHead1;
        }
        return cur1;
    }
};

十一、链表相加 II

链表相加(二)_牛客题霸_牛客网

其实就是高精度加法模拟,之前做过一道还帮我们逆转好了链表,这题还要我们自己逆转,真是可恶。不过链表逆转我们已经很熟悉了,高精度加法也刷过很多次了,无非就是1+1=2的问题。

cpp 复制代码
class Solution {
public:
    ListNode* ReverseNode(ListNode*head)
    {
        if(!head||!head->next)return head;

        ListNode* newhead=ReverseNode(head->next);
        head->next->next=head;
        head->next=nullptr;
        return newhead;
    }
    // ListNode* ReverseNode(ListNode*head)
    // {
    //     ListNode*prev=nullptr;
    //     ListNode*cur=head;
    //     while(cur)
    //     {   
    //         ListNode*t=cur->next;
    //         cur->next=prev;
    //         prev=cur;
    //         cur=t;
    //     }
    //     return prev;
    // }
    ListNode* addInList(ListNode* head1, ListNode* head2) {
        //逆转链表
        ListNode*cur1=ReverseNode(head1),*cur2=ReverseNode(head2);
        int add=0;
        ListNode*newhead=new ListNode(-1);
        while(cur1||cur2||add)
        {
            if(cur1)
            {
                add+=cur1->val;
                cur1=cur1->next;
            }
            if(cur2)
            {
                add+=cur2->val;
                cur2=cur2->next;
            }
            //头插
            ListNode*Node=new ListNode(add%10);
            Node->next=newhead->next;
            newhead->next=Node;
            add/=10;
        }
        ListNode*prev=newhead->next;
        delete newhead;
        return prev;
    }
};

十二、单链表的排序

单链表的排序_牛客题霸_牛客网

666昨天学校布置的作业就写到这个,刚好今天当作复习了

解法一:冒泡排序

链表的冒泡排序(真)不过这不符合题目要求这里我只是展示一下链表的冒泡如何操作

cpp 复制代码
    ListNode* sortInList(ListNode* head) {
        if(!head||!head->next)return head;
        ListNode* newhead=new ListNode(-1),*prev,*cur;
        newhead->next=head;
        bool flag;
        do{
            //更新flag!!!
            flag=false;
            prev=newhead;
            cur=head;
            //NextNode始终是cur下一个要比较的结点
            ListNode* NextNode=cur->next;
            while(NextNode)
            {
                if(cur->val>NextNode->val)
                {
                    cur->next=NextNode->next;
                    NextNode->next=cur;
                    prev->next=NextNode;

                    prev=NextNode;
                    flag=true;
                }
                else {
                prev=cur;
                cur=cur->next;
                }
                NextNode=cur->next;
            }
        }while(flag);
        prev=newhead->next;
        delete newhead;
        return prev;
    }   

虚假的链表冒泡排序,也就是只交换val

cpp 复制代码
    ListNode* sortInList(ListNode* head) {
        if(!head||!head->next)return head;
        ListNode*cur;
        bool flag;
        do{
            //更新flag!!!
            flag=false;
            cur=head;
            //NextNode始终是cur下一个要比较的结点
            ListNode* NextNode=cur->next;
            while(NextNode)
            {
                if(cur->val>NextNode->val)
                {
                    int tmp=cur->val;
                    cur->val=NextNode->val;
                    NextNode->val=tmp;
                }
                cur=cur->next;
                NextNode=cur->next;
            }
        }while(flag);
        return head;
    }   

解法二:归并排序(分治)

题目要求时间复杂度nlogn,那不就是分治了

创建快慢指针->分

排序->治

cpp 复制代码
    ListNode* merge(ListNode*pHead1,ListNode*pHead2)
    {
        if(!pHead1)return pHead2;
        if(!pHead2)return pHead1;

        ListNode* head=new ListNode(0),*cur=head;
        while(pHead1&&pHead2)
        {
            if(pHead1->val<pHead2->val)
            {
                cur->next=pHead1;
                pHead1=pHead1->next;
            }
            else {
                cur->next=pHead2;
                pHead2=pHead2->next;
            }
            //注意移动指针!!!
            cur=cur->next;
        }
        if(pHead1)cur->next=pHead1;
        if(pHead2)cur->next=pHead2;
        cur=head->next;
        delete head;
        return cur;
    }
    ListNode* sortInList(ListNode* head) {
        if(!head||!head->next)return head;

        ListNode*left=head,*mid=head->next,*right=mid->next;
        while(right&&right->next)
        {
            left=left->next;
            mid=mid->next;
            right=right->next->next;
        }
        //断开两个链表,分!
        left->next=nullptr;
        //不断在sortInList里分,分,分
        return merge(sortInList(head),sortInList(mid));
    }

解法三:转换为数组排序

说实话我感觉这种方法有点偷懒哈哈哈,最先想到的也是这个,果然大脑还是喜欢偷懒

cpp 复制代码
    ListNode* sortInList(ListNode* head) {
        vector<int> nums;
        ListNode*cur=head;
        //数据push进数组
        while(cur)
        {
            nums.push_back(cur->val);
            cur=cur->next;
        }
        cur=head;
        sort(nums.begin(),nums.end());
        for(int i=0;i<nums.size();++i)
        {
            cur->val=nums[i];
            cur=cur->next;
        }
        return head;
    }

十三、判断一个链表是否为回文结构

判断一个链表是否为回文结构_牛客题霸_牛客网

解法一:存进数组

也是借鉴了上一题,然后判断,不过感觉这样写很耍赖

cpp 复制代码
    bool isPail(ListNode* head) {
        vector<int> nums;
        ListNode*cur=head;
        while(cur)
        {
            nums.push_back(cur->val);
            cur=cur->next;
        }
        for(int left=0,right=nums.size()-1;left<=right;++left,--right)
        {
            if(nums[left]!=nums[right])return false;
        }
        return true;
    }

解法二:逆转链表+双指针

从中间位置断开,逆转后部分链表,然后双指针判断

或者像这样用头插实现逆转

cpp 复制代码
    bool isPail(ListNode* head) {
        ListNode*dummy=new ListNode(0),*cur1=head;
        while(cur1)
        {
            ListNode*node=new ListNode(cur1->val);
            node->next=dummy->next;
            dummy->next=node;

            //不要忘记移动cur1!
            cur1=cur1->next;
        }
        ListNode*cur2=dummy->next;
        cur1=head;
        while(cur1)
        {
            if(cur1->val!=cur2->val)return false;
            cur1=cur1->next;
            cur2=cur2->next;
        }
        return true;
    }

找中点,再逆序的写法:

cpp 复制代码
    ListNode* ReverseList(ListNode* head)
    {
        if(!head||!head->next)return head;

        ListNode*newnode=ReverseList(head->next);

        head->next->next=head;
        head->next=nullptr;
        return newnode;
    }
    bool isPail(ListNode* head) {
        ListNode*slow=head,*fast=head;
        while(fast&&fast->next)
        {
            slow=slow->next;
            fast=fast->next->next;
        }
        ListNode* ReverseHead=ReverseList(slow);
        ListNode*cur1=head,*cur2=ReverseHead;
        //奇偶统一,cur1&&cur2,有可能cur2先结束,所以要算上cur2
        while(cur1&&cur2)
        {
            if(cur1->val!=cur2->val)return false;
            cur1=cur1->next;
            cur2=cur2->next;
        }
        return true;
    }

解法三:栈

先将数据全部存进栈,每次从栈顶取出的元素就是逆序的

cpp 复制代码
    bool isPail(ListNode* head) {
        stack<int> st;
        ListNode*cur=head;
        while(cur)
        {
            st.push(cur->val);
            cur=cur->next;
        }
        cur=head;
        while(!st.empty())
        {
            if(st.top()!=cur->val)return false;
            st.pop();
            cur=cur->next;
        }
        return true;
    }

十四、链表的奇偶重排

链表的奇偶重排_牛客题霸_牛客网

朴素解法:

cpp 复制代码
ListNode* oddEvenList(ListNode* head) {
        if(!head||!head->next||!head->next->next)return head;

        ListNode*cur=head,*newnode=new ListNode(0),*p=newnode;
        while(cur)
        {   
            //不能直接指向cur1,要创建新结点
            p->next=new ListNode(cur->val);
            p=p->next;
            //cur->next不存在说明是尾部,那么得置为nullptr,
            //开始时没有做处理导致死循环了emm
            cur=cur->next?cur->next->next:nullptr;
        }
        cur=head->next;
        while(cur)
        {
            p->next=new ListNode(cur->val);
            p=p->next;
            cur=cur->next?cur->next->next:nullptr;
        }
        p=newnode->next;
        delete newnode;
        return p;
    }

题解:相当于在原链表上直接修改指向

cpp 复制代码
class Solution {
public:
    ListNode* oddEvenList(ListNode* head) {
        //如果链表为空,不用重排
        if(head == NULL) 
            return head;
        //even开头指向第二个节点,可能为空
        ListNode* even = head->next; 
        //odd开头指向第一个节点
        ListNode* odd = head; 
        //指向even开头
        ListNode* evenhead = even; 
        while(even != NULL && even->next != NULL){ 
            //odd连接even的后一个,即奇数位
            odd->next = even->next; 
            //odd进入后一个奇数位
            odd = odd->next; 
            //even连接后一个奇数的后一位,即偶数位
            even->next = odd->next; 
            //even进入后一个偶数位
            even = even->next; 
        } 
        //even整体接在odd后面
        odd->next = evenhead; 
        return head;
    }
};

十五、删除有序链表中重复的元素

删除有序链表中重复的元素-I_牛客题霸_牛客网

法一:双指针

本来还写了排序的,后来发现题目里的链表是排好的,法科

cpp 复制代码
#include <climits>
class Solution {
public:
    // ListNode*merge(ListNode*pHead1,ListNode*pHead2)
    // {
    //     ListNode*newhead=new ListNode(0),*cur=newhead;
    //     while(pHead1&&pHead2)
    //     {
    //         if(pHead1->val<pHead2->val)
    //         {
    //             cur->next=pHead1;
    //             pHead1=pHead1->next;
    //         }
    //         else {
    //             cur->next=pHead2;
    //             pHead2=pHead2->next;
    //         }
    //         cur=cur->next;
    //     }
    //     if(pHead1)cur->next=pHead1;
    //     if(pHead2)cur->next=pHead2;
    //     cur=newhead->next;
    //     delete newhead;
    //     return cur;
    // }
    // ListNode* SortList(ListNode*head)
    // {
    //     if(!head||!head->next)return head;

    //     ListNode*left=head,*mid=head->next,*right=mid->next;
    //     while(right&&right->next)
    //     {
    //         left=mid;
    //         mid=right;
    //         right=right->next;
    //     }
    //     left->next=nullptr;
    //     return merge(SortList(head),SortList(mid));
    // }
    ListNode* deleteDuplicates(ListNode* head) {
        if(!head||!head->next)return head;
        //ListNode* NewHead=SortList(head);
        //cur存不重复的当前结点,next负责遍历
        ListNode*cur=head,*next=cur->next;
        while(next)
        {
            if(next->val==cur->val)next=next->next;
            else
             {
                cur->next=next;
                cur=next;
                next=cur->next;
             }
        }
        //断开后续所有结点
        cur->next=nullptr;
        return head;
    }
};

解法二:单指针简单遍历即可

官方代码用单指针也可以实现:推荐

cpp 复制代码
    ListNode* deleteDuplicates(ListNode* head) {
        if(!head||!head->next)return head;
        ListNode*cur=head;
        while(cur&&cur->next)
        {
            if(cur->val==cur->next->val)
            {
                //跳过cur->next
                cur->next=cur->next->next;
            }
            //遇到不等的了,说明当前和cur相等的val已经全部跳过
            //cur->next存的是下一个要处理的val,更新cur
            else cur=cur->next;
        }
        return head;
    }

十六、删除有序链表中重复的元素II

删除有序链表中重复的元素-II_牛客题霸_牛客网

这次出现次数大于1的直接被删了,就像玩开心消消乐那样

现在就是如果cur->next的值与cur的值相等,那么cur是被跳过的那个,如果开头第一个元素就是跳过的,为了方便操作,我们引入虚拟头结点。思路重在修改指向。

cpp 复制代码
    ListNode* deleteDuplicates(ListNode* head) {
        if (!head || !head->next)return head;
        //创建新表头,直接从新表头开始修改方向
        ListNode* newhead = new ListNode(0), *cur = newhead;
        newhead->next = head;
        while (cur ->next&& cur->next->next) {
            //相等跳过这一整段
            if (cur->next->val == cur->next->next->val) {
                int tmp=cur->next->val;
                while (cur->next && cur->next->val==tmp) {
                    cur ->next=cur->next->next;
                }
            }
            //不等的表示符合,cur直接找下一个结点
            else {
                cur=cur->next;
            }
        }
        cur= newhead->next;
        delete newhead;
        return cur;
    }

链表结束。

相关推荐
JJJJ_iii3 小时前
【机器学习06】神经网络的实现、训练与向量化
人工智能·笔记·深度学习·神经网络·学习·机器学习·线性回归
wuk9983 小时前
基于位置式PID算法调节PWM占空比实现电机转速控制
单片机·嵌入式硬件·算法
sakoba3 小时前
MySQL的json处理相关方法
android·学习·mysql·json
序属秋秋秋3 小时前
《Linux系统编程之入门基础》【Linux基础 理论+命令】(下)
linux·运维·服务器·学习·ubuntu·xshell·命令
派大星爱吃猫3 小时前
堆的概念、结构与应用详解
c语言·数据结构·
不到满级不改名3 小时前
EM算法 & 隐马尔可夫模型
算法
瑞士卷@3 小时前
spring从入门到精通(spring学习笔记,持续更新中)
笔记·学习·spring
蓝创精英团队3 小时前
C++DirectX9坐标系与基本图元之渲染状态(RenderState)_0304
前端·c++·性能优化
我先去打把游戏先3 小时前
ESP32学习笔记(基于IDF):SmartConfig一键配网
笔记·嵌入式硬件·mcu·物联网·学习·esp32·硬件工程