C/C++牛客网刷题练习之翻转链表篇

简介: C/C++牛客网刷题练习之翻转链表篇

一、反转链表


题目要求


我的题解


既然是使用vector容器来做这道题,那么就在判断链表不为空的情况下把链表的结点全部放进vector容器中,然后调用reverse(v.begin(),v.end());函数将容器的元素反转,最后将容器中的元素赋值给一个新创建的链表并返回该链表即可。

具体代码


class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if(!pHead) return nullptr;
        vector<ListNode*>v;
        while(pHead){
            v.push_back(pHead);
            pHead=pHead->next;
        }
        reverse(v.begin(),v.end());
        ListNode *head=*v.begin();
        ListNode *ptr=head;
        for(int i=1;i<v.size();i++){
            ptr->next=v[i];
            ptr=ptr->next;
        }
        ptr->next=NULL;
        return head;
    }
};


ListNode *head=*v.begin(); 这段代码的意思是新建的head结点指向反转后容器中的第一个元素,因为v.begin()是一个迭代器,只有加上"*"解引用之后才是结点。最后让ptr的指针指向NULL,这样做是防止测试代码的时候不能正常的停止遍历,防止死循环。


二、链表内指定区间反转


题目要求



我的题解


这题的意思就是在链表中指定一段区间进行反转,我还利用vector容器来操作。

首先排除区间为一的情况,如果区间为一,也就是m==n,直接返回链表即可;然后将链表全部存进vector中,然后把m和n的区间表示出来,通过一个while循环把指定区间的结点值反转;最后再把容器中的元素取出来放进新建的链表并返回即可。


具体代码


class Solution {
public:
    /**
     * @param head ListNode类 
     * @param m int整型 
     * @param n int整型 
     * @return ListNode类
     */
    ListNode* reverseBetween(ListNode* head, int m, int n) {
        // write code here
        if(m==n) return head;
        vector<ListNode*> v;
        int l=m-1,r=n-1;
        while(head){
            v.push_back(head);
            head=head->next;
        }
        while(l<r){
            int k=v[l]->val;
            v[l]->val=v[r]->val;
            v[r]->val=k;
            l++;
            r--;
        }
        ListNode *L=*v.begin();
        ListNode *ptr=L;
        for(int i=1;i<v.size();i++){
            ptr->next=v[i];
            ptr=ptr->next;
        }
        ptr->next=NULL;
        return L;
    }
};


这样的思路很好理解吧,和第一题的步骤几乎一样,只是多了一个while循环来把指定区间的元素值进行反转,这样循序渐进可以加深这个借助vector容器来辅助解决问题的思想。

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


题目要求



我的题解


这一题我想到的是要先分块进行翻转操作,最后再进行链表拼接。再三考虑下我选择了递归的方法,目的就是把所有的"块"翻转完之后能立刻拼接并返回该链表,这样不就能解决问题了吗。具体实现过程我会在该题具体代码的下面详解。


具体代码


class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        if(!head || k <= 1) return head; //空指针及不需要翻转的情况直接返回head
        ListNode* pre = nullptr; //pre指向右移前的当前结点
        ListNode* cur = head; //记录当前ListNode
        ListNode* next = nullptr; //记录下一个ListNode
        //检测是否进行反转
        for(int i = 0; i < k; i++) { //检测ListNode数量是否大于k
            if(!cur) return head; //若不大于直接返回头
            cur = cur->next; //指向下一个ListNode
        }
        cur = head; //检测完毕后cur复原成头
        for(int i = 0; i < k; i++) {
            next = cur->next; //记录后一个ListNode
            cur->next = pre; //cur指向前一个ListNode
            pre = cur; //pre成为新的头结点并右移
            cur = next; //cur右移
        }
        head->next = reverseKGroup(next, k); //此时k个ListNode翻转完毕,head其实就是反转后的pre
        return pre; //返回新的头
    }
};


这段代码的核心部分就从第二个for循环开始了,首先利用next指针记录组内第二个结点;然后将pre指针插入到当前结点之后,将pre结点左移,这样pre就代表头结点且值为当前结点的值,然后当前结点右移,指向之前next记录的位置;循环的最终结果是该组的结点完成翻转,且pre为与head指向相同,让head指向下一个结点的递归结点即可,最后全部翻转后返回pre,程序结束。


动态图解


相关文章
|
9月前
|
存储 监控 算法
公司监控上网软件架构:基于 C++ 链表算法的数据关联机制探讨
在数字化办公时代,公司监控上网软件成为企业管理网络资源和保障信息安全的关键工具。本文深入剖析C++中的链表数据结构及其在该软件中的应用。链表通过节点存储网络访问记录,具备高效插入、删除操作及节省内存的优势,助力企业实时追踪员工上网行为,提升运营效率并降低安全风险。示例代码展示了如何用C++实现链表记录上网行为,并模拟发送至服务器。链表为公司监控上网软件提供了灵活高效的数据管理方式,但实际开发还需考虑安全性、隐私保护等多方面因素。
182 0
公司监控上网软件架构:基于 C++ 链表算法的数据关联机制探讨
|
程序员
【刷题记录】移除链表元素
【刷题记录】移除链表元素
104 0
|
10月前
|
机器学习/深度学习 存储 C++
【C++数据结构——线性表】单链表的基本运算(头歌实践教学平台习题)【合集】
本内容介绍了单链表的基本运算任务,涵盖线性表的基本概念、初始化、销毁、判定是否为空表、求长度、输出、求元素值、按元素值查找、插入和删除数据元素等操作。通过C++代码示例详细解释了顺序表和链表的实现方法,并提供了测试说明、通 - **任务描述**:实现单链表的基本运算。 - **相关知识**:包括线性表的概念、初始化、销毁、判断空表、求长度、输出、求元素值、查找、插入和删除等操作。 - **测试说明**:平台会对你编写的代码进行测试,提供测试输入和预期输出。 - **通关代码**:给出了完整的C++代码实现。 - **测试结果**:展示了测试通过后的预期输出结果。 开始你的任务吧,祝你成功!
478 5
|
Python
【Leetcode刷题Python】剑指 Offer 22. 链表中倒数第k个节点
Leetcode题目"剑指 Offer 22. 链表中倒数第k个节点"的Python解决方案,使用双指针法找到并返回链表中倒数第k个节点。
189 5
【刷题记录】链表的回文结构
【刷题记录】链表的回文结构
|
Python
【Leetcode刷题Python】剑指 Offer 18. 删除链表的节点
Leetcode题目"剑指 Offer 18. 删除链表的节点"的Python解决方案,通过使用双指针法找到并删除链表中值为特定数值的节点,然后返回更新后的链表头节点。
180 4
|
机器学习/深度学习
【刷题记录】相交链表
【刷题记录】相交链表
【刷题记录】链表的中间结点
【刷题记录】链表的中间结点
|
9月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
5月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
154 0

热门文章

最新文章