代码随想录笔记--链表篇

news2024/7/6 19:26:54

目录

1--虚拟头节点的使用

2--设计链表

3--反转链表

4--两两交换链表中的节点

5--快慢指针

5-1--删除链表倒数第N个节点

5-2--环形链表

5-3--环形链表II


1--虚拟头节点的使用

        在链表相关题目中,常新定义一个虚拟头结点 dummynode 来指向原链表的头结点,当需要返回链表时,只需返回 dummynode->next;

#include <iostream>

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) {}
};

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        if(head==nullptr) return head;
        ListNode* dummynode = new ListNode(); // 新建虚拟头结点
        dummynode->next = head;
        ListNode* cur = dummynode;
        while(cur->next != nullptr){
            if(cur->next->val == val){
                ListNode* tmp = cur->next;
                cur->next = cur->next->next;
                delete tmp;
                tmp = nullptr;
            }
            else{
                cur = cur->next;
            }
        }
        return dummynode->next;
    }
};

int main(int arc, char *argv[]){
    ListNode* Node1 = new ListNode(1);
    ListNode* Node2 = new ListNode(2);
    ListNode* Node3 = new ListNode(6);
    ListNode* Node4 = new ListNode(3);
    ListNode* Node5 = new ListNode(4);
    ListNode* Node6 = new ListNode(5);
    ListNode* Node7 = new ListNode(6);

    Node1->next = Node2;
    Node2->next = Node3;
    Node3->next = Node4;
    Node4->next = Node5;
    Node5->next = Node6;
    Node6->next = Node7;

    Solution S1;
    int val = 6;
    ListNode* res = S1.removeElements(Node1, val);
    ListNode* cur = res;
    while(cur != NULL){
        std::cout << cur->val << " ";
        cur = cur->next;
    }
    return 0;
}

2--设计链表

#include <iostream>

class MyLinkedList {
public:
    // 定义链表节点结构体
    struct LinkedNode {
        int val;
        LinkedNode* next;
        LinkedNode(int val):val(val), next(nullptr){}
    };

    // 初始化链表
    MyLinkedList() {
        _dummyHead = new LinkedNode(0); // 虚拟头结点
        _size = 0;
    }

    int get(int index) {
        if (index > (_size - 1) || index < 0) { // 不合法index
            return -1;
        }
        LinkedNode* cur = _dummyHead->next;
        while(index--){
            cur = cur->next;
        }
        return cur->val;
    }

    void addAtHead(int val) {
        LinkedNode* newNode = new LinkedNode(val);
        newNode->next = _dummyHead->next;
        _dummyHead->next = newNode;
        _size++;
    }

    void addAtTail(int val) {
        LinkedNode* newNode = new LinkedNode(val);
        LinkedNode* cur = _dummyHead;
        while(cur->next != nullptr){
            cur = cur->next;
        }
        cur->next = newNode;
        _size++;
    }

    void addAtIndex(int index, int val) {

        if(index > _size) return;
        if(index < 0) index = 0;        
        LinkedNode* newNode = new LinkedNode(val);
        LinkedNode* cur = _dummyHead;
        while(index--) {
            cur = cur->next;
        }
        newNode->next = cur->next;
        cur->next = newNode;
        _size++;
    }

    void deleteAtIndex(int index) {
        if (index >= _size || index < 0) {
            return;
        }
        LinkedNode* cur = _dummyHead;
        while(index--) {
            cur = cur ->next;
        }
        LinkedNode* tmp = cur->next;
        cur->next = cur->next->next;
        delete tmp;
        tmp=nullptr;
        _size--;
    }

    // 打印链表
    void printLinkedList() {
        LinkedNode* cur = _dummyHead;
        while (cur->next != nullptr) {
            std::cout << cur->next->val << " ";
            cur = cur->next;
        }
        std::cout << std::endl;
    }
private:
    int _size;
    LinkedNode* _dummyHead;

};

int main(int arc, char *argv[]){
    MyLinkedList myLinkedList;
    myLinkedList.addAtHead(1);
    myLinkedList.addAtTail(3);
    myLinkedList.addAtIndex(1, 2);    // 链表变为 1->2->3
    std::cout << myLinkedList.get(1) << std::endl;  // 返回 2
    myLinkedList.deleteAtIndex(1);    // 现在,链表变为 1->3
    std::cout << myLinkedList.get(1) << std::endl;  // 返回 3
    return 0;
}

3--反转链表

双指针解法: 

#include <iostream>

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) {}
};

class Solution {
public:
    ListNode* reverseList(ListNode* head){
        if(head == nullptr) return head;
        ListNode *pre = nullptr;
        ListNode *cur = head;
        while(cur != NULL){
            ListNode *tmp = cur->next;
            cur->next = pre;
            pre = cur;
            cur = tmp;
        }
        return pre;
    }
};

int main(int arc, char *argv[]){
    ListNode *Node1 = new ListNode(1);
    ListNode *Node2 = new ListNode(2);
    ListNode *Node3 = new ListNode(3);
    ListNode *Node4 = new ListNode(4);
    ListNode *Node5 = new ListNode(5);

    Node1->next = Node2;
    Node2->next = Node3;
    Node3->next = Node4;
    Node4->next = Node5;

    Solution S1;
    ListNode *res = S1.reverseList(Node1);
    ListNode *cur = res;
    while(cur != NULL){
        std::cout << cur->val << " ";
        cur = cur->next;
    }
    return 0;
}

递归写法:

#include <iostream>

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) {}
};

class Solution {
public:
    ListNode* reverseList(ListNode* head){
        if(head == nullptr) return head;
        return reverse(head, nullptr);
    }

    ListNode* reverse(ListNode* cur, ListNode* pre){
        if(cur == nullptr) return pre;
        ListNode *tmp = cur->next;
        cur->next = pre;
        return reverse(tmp, cur);
    }
};

int main(int arc, char *argv[]){
    ListNode *Node1 = new ListNode(1);
    ListNode *Node2 = new ListNode(2);
    ListNode *Node3 = new ListNode(3);
    ListNode *Node4 = new ListNode(4);
    ListNode *Node5 = new ListNode(5);

    Node1->next = Node2;
    Node2->next = Node3;
    Node3->next = Node4;
    Node4->next = Node5;

    Solution S1;
    ListNode *res = S1.reverseList(Node1);
    ListNode *cur = res;
    while(cur != NULL){
        std::cout << cur->val << " ";
        cur = cur->next;
    }
    return 0;
}

4--两两交换链表中的节点

#include <iostream>

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) {}
};

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(head == nullptr) return head;
        ListNode *dummyNode = new ListNode();
        dummyNode->next = head;
        ListNode *cur = dummyNode;
        while(cur->next != nullptr && cur->next->next != nullptr){
            ListNode *tmp1 = cur->next;
            ListNode *tmp2 = cur->next->next->next;
            cur->next = cur->next->next;
            cur->next->next = tmp1;
            tmp1->next = tmp2;
            cur = cur->next->next;
        }
        return dummyNode->next;
    }
};

int main(int arc, char *argv[]){
    ListNode *Node1 = new ListNode(1);
    ListNode *Node2 = new ListNode(2);
    ListNode *Node3 = new ListNode(3);
    ListNode *Node4 = new ListNode(4);

    Node1->next = Node2;
    Node2->next = Node3;
    Node3->next = Node4;

    Solution S1;
    ListNode *res = S1.swapPairs(Node1);
    ListNode *cur = res;
    while(cur != NULL){
        std::cout << cur->val << " ";
        cur = cur->next;
    }
    return 0;
}

5--快慢指针

5-1--删除链表倒数第N个节点

快慢指针

#include <iostream>
#include <vector>

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) {}
};

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode *dummyNode = new ListNode();
        dummyNode->next = head;
        ListNode* slow = dummyNode;
        ListNode* fast = dummyNode;
        while(n-- && fast != NULL){
            fast = fast->next;
        }
        while(fast->next != NULL){
            slow = slow->next;
            fast = fast->next;
        }
        ListNode *target = slow->next;
        slow->next = target->next;
        delete target;
        target = nullptr;
        return dummyNode->next;
    }
};

int main(int argc, char argv[]){
    ListNode *Node1 = new ListNode(1);
    ListNode *Node2 = new ListNode(2);
    ListNode *Node3 = new ListNode(3);
    ListNode *Node4 = new ListNode(4);
    ListNode *Node5 = new ListNode(5);

    Node1->next = Node2;
    Node2->next = Node3;
    Node3->next = Node4;
    Node4->next = Node5;

    int n = 2;
    Solution S1;
    ListNode *res = S1.removeNthFromEnd(Node1, n);
    ListNode *cur = res;
    while(cur != NULL){
        std::cout << cur->val << " ";
        cur = cur->next;
    }
    return 0;
}

5-2--环形链表

快慢指针,当链表有环时,快慢指针必定相遇;

#include <iostream>
#include <vector>

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

class Solution {
public:
    bool hasCycle(ListNode *head) {
        if(head == nullptr) return false;
        ListNode *slow = head;
        ListNode *fast = head;
        while(fast != NULL && fast->next != NULL){
            fast = fast->next->next;
            slow = slow->next;
            if(slow == fast) break;
        }
        if(fast == NULL || fast->next == NULL) return false;
        else return true;
    }
};

int main(int argc, char argv[]){
    ListNode *Node1 = new ListNode(1);
    ListNode *Node2 = new ListNode(2);
    ListNode *Node3 = new ListNode(0);
    ListNode *Node4 = new ListNode(-4);

    Node1->next = Node2;
    Node2->next = Node3;
    Node3->next = Node4;
    Node4->next = Node2;

    Solution S1;
    bool res = S1.hasCycle(Node1);
    if(res) std::cout << "true" << std::endl;
    else std::cout << "false" << std::endl;
    return 0;
}

5-3--环形链表II

        快慢指针,快指针每次走两步,慢指针每次走一步,根据快慢指针是否相遇判断是否有环;

        当快慢指针第一次相遇后,慢指针从头出发,快指针从第一次相遇的节点出发,快慢指针均每次走一步,当下一次相遇时就处于环的入口节点,返回即可;

#include <iostream>
#include <vector>

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

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if(head == nullptr) return head;
        ListNode *slow = head;
        ListNode *fast = head;
        while(fast != NULL && fast->next != NULL){
            fast = fast->next->next;
            slow = slow->next;
            if(fast == slow) break; // 第一次相遇
        }
        if(fast == NULL || fast->next == NULL) return NULL; // 没有环
        // 从头开始走
        slow = head;
        while(slow != fast){
            slow = slow->next;
            fast = fast->next;
        }
        // 第二次相遇就是环的入口
        return slow;
    }
};

int main(int argc, char argv[]){
    ListNode *Node1 = new ListNode(1);
    ListNode *Node2 = new ListNode(2);
    ListNode *Node3 = new ListNode(0);
    ListNode *Node4 = new ListNode(-4);

    Node1->next = Node2;
    Node2->next = Node3;
    Node3->next = Node4;
    Node4->next = Node2;

    Solution S1;
    ListNode * res = S1.detectCycle(Node1);
    std::cout << res->val << std::endl;
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/946892.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

常见矿石材质鉴定VR实训模拟操作平台提高学员的学习效果和实践能力

随着“元宇宙”概念的不断发展&#xff0c;在矿山领域中&#xff0c;长期存在传统培训内容不够丰富、教学方式单一、资源消耗大等缺点&#xff0c;无法适应当前矿山企业发展需求的长期难题。元宇宙企业借助VR虚拟现实、web3d开发和计算机技术构建的一个虚拟世界&#xff0c;为用…

华为云新生代开发者招募

开发者您好&#xff0c;我们是华为2012UCD的研究团队 为了解年轻开发者的开发现状和趋势 正在邀请各位先锋开发者&#xff0c;与我们进行2小时的线上交流&#xff08;江浙沪附近可线下交流&#xff09; 聊聊您日常开发工作中的产品使用需求 成功参与访谈者将获得至少300元京…

Angular安全专辑之三:授权绕过,利用漏洞控制管理员账户

这篇文章是针对实际项目中所出现的问题所做的一个总结。简单来说&#xff0c;就是授权绕过问题&#xff0c;管理员帐户被错误的接管。 详细情况是这样的&#xff0c;我们的项目中通常都会有用户身份验证功能&#xff0c;不同的用户拥有不同的权限。相对来说管理员账户所对应的…

嵌入式学习之进程

今天主要学习了进程&#xff0c;对fork的相关知识有了更加清楚的理解。 进程退出 正常调用&#xff1a; Main函数调用return ; 进程调用exit(),属于标准的C库&#xff1b;进程调用_exit&#xff08;&#xff09;或者_Exit(),属于系统调用 补充&#xff1a; 1.进程最后一个…

flutter高德地图大头针

1、效果图 2、pub get #地图定位 amap_flutter_map: ^3.0.0 amap_flutter_location: ^3.0.0 3、上代码 import dart:async; import dart:io;import package:amap_flutter_location/amap_flutter_location.dart; import package:amap_flutter_location/amap_location_option…

frp实现二级代理

kali是攻击机 &#xff08;192.168.0.106&#xff09; windows server2012是边界服务器&#xff0c;拥有两个网卡&#xff0c;作为一级代理&#xff0c; &#xff08;192.168.0.108&#xff0c;10.10.10.136&#xff09; ad01是内网机器&#xff0c;不出网 &#xff08;10.10.1…

linux中学习控制进程的要点

1. 进程创建 1.1 fork函数 #include <unistd.h> pid_t fork(void); 返回值&#xff1a;自进程中返回0&#xff0c;父进程返回子进程id&#xff0c;出错返回-1 进程调用fork&#xff0c;当控制转移到内核中的fork代码后&#xff0c;内核会做以下操作 分配新的内存块和…

从零构建深度学习推理框架-10 算子的执行流程

计算图的设计 Graph的结构 Operators: 记录所有的节点Input operator: 指定的输入节点Output operator: 指定的输出节点Global input data: 模型的外部全局输入&#xff08;用户指定的输入&#xff09; Operator的结构 Input data: 节点的输入数据Output data: 节点的输出数…

JixiPix Artista Impresso Pro for mac(油画滤镜效果软件)

JixiPix Artista Impresso pro Mac是一款专业的图像编辑软件&#xff0c;专为Mac用户设计。它提供了各种高质量的图像编辑工具&#xff0c;可以帮助您创建令人惊叹的图像。该软件具有直观的用户界面&#xff0c;使您可以轻松地浏览和使用各种工具。 它还支持多种文件格式&…

WSL Opencv with_ffmpeg conan1.60.0

我是ubuntu18. self.options[“opencv”].with_ffmpeg True 关键是gcc版本需要conan支持&#xff0c;比如我的是&#xff1a; compilergcc compiler.version7.5 此外还需要安装系统所需库&#xff1a; https://qq742971636.blog.csdn.net/article/details/132559789 甚至来…

db2迁移至oracle

1.思路 &#xff08;1&#xff09;用java连接数据库&#xff08;2&#xff09;把DB2数据导出为通用的格式如csv&#xff0c;json等&#xff08;3&#xff09;导入其他数据库&#xff0c;比如oracle&#xff0c;mongodb。这个方法自由发挥的空间比较大。朋友说他会用springboot…

Spring Cloud + Spring Boot 项目搭建结构层次示例讲解

Spring Cloud Spring Boot 项目搭建结构层次示例讲解 Spring Cloud 项目搭建结构层次示例Spring Cloud示例&#xff1a; Spring Boot 项目搭建结构层次讲解Spring Boot 项目通常按照一种常见的架构模式组织&#xff0c;可以分为以下几个主要层次&#xff1a;当构建一个 Spring…

fastjson windows主机上线

首先创建一个win类&#xff0c;作为命令执行的类 然后写一个漏洞Fastjson的执行类 将我们的win类传上vps 然后开启web服务 接下来利用ldap协议 java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://185.239.225.205:80/#win 6666然后我们运…

基于骑手优化算法优化的BP神经网络(预测应用) - 附代码

基于骑手优化算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码 文章目录 基于骑手优化算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码1.数据介绍2.骑手优化优化BP神经网络2.1 BP神经网络参数设置2.2 骑手优化算法应用 4.测试结果&#xff1a;5…

Doris数据库BE——rowset版本追踪

rowset代码位置be/src/olap/version_graph.cpp&#xff0c;字面意思行集合&#xff0c;由一行或多行组成。rowset版本简单理解为rowset编号&#xff0c;每次导入生成一个rowset&#xff0c;比如insert执行10次会生成10个rowset&#xff0c;一次streamload生成一个rowset。 版本…

Pillow:Python的图像处理库(安装与使用教程)

在Python中&#xff0c;Pillow库是一个非常强大的图像处理库。它提供了广泛的图像处理功能&#xff0c;让我们可以轻松地操作图像&#xff0c;实现图像的转换、裁剪、缩放、旋转等操作。此外&#xff0c;Pillow还支持多种图像格式的读取和保存&#xff0c;包括JPEG、PNG、BMP、…

LeetCode 热题 100(七):105. 从前序与中序遍历序列构造二叉树、14. 二叉树展开为链表

题目一&#xff1a; 105. 从前序与中序遍历序列构造二叉树https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ 思路&#xff1a;依据前序遍历的根左右和中序遍历的左根右&#xff0c; 且根左长度&#xff1d;左根 代码&#xff1a; …

直播预告:把脉2023年下半场—主动防御邮箱盗号威胁

长期以来&#xff0c;承载着大量敏感数据的企业是黑产团伙的首要攻击目标。Coremail结合多年以来的邮件防护经验发现&#xff0c;黑产团伙针对企业邮箱账号安全的两大攻击方式为暴力破解和钓鱼邮件攻击。 一、企业邮箱安全现状 01、使用弱密码 企业员工使用弱密码让黑产团伙有…

docker 学习-- 04 实践2 (lnpmr环境)

docker 学习 系列文章目录 docker 学习-- 01 基础知识 docker 学习-- 02 常用命令 docker 学习-- 03 环境安装 docker 学习-- 04 实践 1&#xff08;宝塔&#xff09; docker 学习-- 04 实践 2 &#xff08;lnpmr环境&#xff09; 文章目录 docker 学习 系列文章目录1. 配…

QSqlDatabase(2)实例,QTableView显示数据库表数据

目录 前言 1、实现的功能 2、具体的代码实现 前言 想了解QSqlDatabase基本知识的&#xff0c;以及增删改查的用法&#xff0c;可以浏览上一篇文章&#xff1a; QSqlDatabase&#xff08;1&#xff09;基本接口&#xff0c;以及(增删改除)的简单实例_Ivy_belief的博客-CSDN…