数据结构初阶--链表OJ

news2024/11/15 22:40:58

目录

  • 前言
  • 移除链表元素
    • 思路分析
    • 代码实现
  • 链表的中间节点
    • 思路分析
    • 代码实现
  • 反转链表
    • 思路分析
    • 代码实现
  • 链表分割
    • 思路分析
    • 代码实现
  • 合并两个有序链表
    • 思路分析
    • 代码实现

前言

本篇文章将对部分单链表的OJ题进行讲解

移除链表元素

我们先来看题

思路分析

我们可以采用双指针的方法来解决这个问题,我们用cur指针来遍历链表,找到待删除的元素,并用一个prev指针来保存上一个节点,使该结点的next指向cur结点的next(即待删除元素下一个节点的地址),如果没找到,就将prev指向cur,cur指向cur->next进行迭代。
注意,我们还要考虑第一个节点的val就是待删除元素的情况,这时候的头节点就应该指向下一个节点。

代码实现

代码的实现如下

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* removeElements(struct ListNode* head, int val){
        struct ListNode*prev=NULL,*cur=head;
    while(cur)
    {
        if(cur->val==val)
        {
            if(cur==head)
            {
                head=cur->next;
                cur=head;
            }
            else
            {
                prev->next=cur->next;
                free(cur);
                cur=prev->next;
            }
        }
        else
        {
            prev=cur;
            cur=cur->next;
        }
    }
    return head;
}

链表的中间节点

先来看题目描述

思路分析

我们常规的思路是先用cur遍历一遍链表,并保存其长度,然后再遍历长度的一半次,返回最后的节点位置,这个方法可行,但是需要遍历两次链表,有没有方法能只遍历一遍链表就能找出中间节点呢?
当然可以,这里采用的就是快慢指针的方法,慢指针每次走一步,快指针每次走两步当快指针的下一个节点为空时停止遍历,此时慢指针指向的就是中间节点

代码实现

代码实现如下

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* middleNode(struct ListNode* head){
    struct ListNode* slow=head;
    struct ListNode* fast=head;
    while(fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
        if(fast==NULL)
        break;
    }
    return slow;

}

反转链表

思路分析

这道题的思路和我们以前做过的<font color=orange.数组元素逆置十分相像,我们知道,要想交换两个位置的值,需要一个中间变量才能实现,所以本题我们也创建一个新的节点来临时保存其中的一个节点,防止出现找不到节点的情况,然后再将节点尾插的即可

代码实现

代码实现如下

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* reverseList(struct ListNode* head){
    struct ListNode* cur=head;
    struct ListNode* pre=NULL;
    while(cur)
    {
        struct ListNode* tmp=cur->next;
        cur->next=pre;
        pre=cur;
        cur=tmp;
    }

    return pre;

}

链表分割

先来看题目描述

思路分析

1,我们令cur=pHead
2,让cur遍历链表,再开辟两个新结点lessHead和greaterHead,把链表分为两部分,第一部分是小于x的结点放在lessHead->next里,大于x的结点放在greaterHead->next里
3,当cur走到NULL时,让lessTail->next=greaterHead->next,这样就把两个链表按照原来的相对顺序连接起来
4,返回lessHead->next.

代码实现

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) {
        // write code here
        struct ListNode* greatHead, *greattail, *lessHead, *lesstail, *cur;
        greatHead = greattail = (struct ListNode*)malloc(sizeof(struct ListNode));
        lessHead = lesstail = (struct ListNode*)malloc(sizeof(struct ListNode));
        cur = pHead;
        while(cur)
        {
            if(cur->val < x)
            {
                lesstail->next = cur;  
                lesstail = cur;   
                cur = cur->next; 
            }
            else
            {
                greattail->next = cur;
                greattail = cur;
                cur = cur->next;
            }
        }
         
        lesstail->next = greatHead->next;  
        greattail->next = NULL;   
         
        return lessHead->next;
    }
};

合并两个有序链表

还是先来看题目描述

思路分析

  1. 我们首先考虑其中一个链表为空的情形,这样就只用返回另一个头节点即可。
  2. 然后我们malloc一个节点pS,作为哨兵位,这样就可以避免区分第一个节点是否为空的问题,然后分别遍历list1和list2,用temp指针来接收节点并往后走。
  3. 当list1或list2有一个为空时停止遍历然后判断另一个链表是否为空,若不为空,则将temp->next指向不为空的链表的头结点进行链接。
  4. 最后返回pS->next.

代码实现

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
    if(list1==NULL) {
        return list2;
    } else if(list2==NULL) {
        return list1;
    }

    struct ListNode* pS=(struct ListNode*)malloc(sizeof(struct ListNode));
    struct ListNode* temp=pS;
    while(list1!=NULL && list2!=NULL) {
        if(list1->val<=list2->val) {
            temp->next=list1;
            list1=list1->next;
        } else {
            temp->next=list2;
            list2=list2->next;
        }
        temp=temp->next;
    }

    if(list1!=NULL) {
        temp->next=list1;
    } 
    if(list2!=NULL) {
        temp->next=list2;
    }

    return pS->next;
}

以上就是本篇文章的全部内容,如有出入,欢迎指正。

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

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

相关文章

测试常见概念

文章目录 需求测试用例BUG软件生命周期开发模型scrum测试模型 需求 需求的概念&#xff1a;满足用户期望或正式规定文档(合同、标准、规范)所具有的条件和权能&#xff0c;包含用户需求和软件需求 用户需求&#xff1a;可以简单理解为甲方提出的需求&#xff0c;如果没有甲方&…

java错题总结(19-21页)

链接&#xff1a;关于Java中的ClassLoader下面的哪些描述是错误的_用友笔试题_牛客网 来源&#xff1a;牛客网 B&#xff1a;先讲一下双亲委派机制&#xff0c;简单来说&#xff0c;就是加载一个类的时候&#xff0c;会往上找他的父类加载器&#xff0c;父类加载器找它的父类加…

Netty(1)

Netty 文章目录 Netty1 Netty 基本介绍2 why Netty2.1 原生 NIO 问题2.2 Netty 优点 3 I/O 线程模型3.1 传统阻塞 I/O 模型3.2 Reactor 模式3.2.1 Reactor 模式解决传统 I/O 方案3.2.2 Reactor 模式原理图3.2.3 Reactor 的核心组件3.2.4 单 Readcot 单线程(NIO模型)3.2.5 单 Re…

非科班转码,春招总结!

作者&#xff1a;阿秀 校招八股文学习网站&#xff1a;https://interviewguide.cn 这是阿秀的第「263」篇原创 小伙伴们大家好&#xff0c;我是阿秀。 欢迎今年参加秋招的小伙伴加入阿秀的学习圈&#xff0c;目前已经超过 2300 小伙伴加入&#xff01;去年认真准备和走下来的基…

Twitter 推荐算法底有多牛? 已斩获11.7K star

点击上方“Github中文社区”&#xff0c;关注 看Github&#xff0c;每天提升第070期分享 &#xff0c;作者&#xff1a;Huber | Github中文社区 大家好&#xff0c;我是Huber。 在美国当地时间 3 月 31 日&#xff0c;马斯克履行当初的诺言&#xff0c;他宣布了 Twitter 算法的…

《编程思维与实践》1048.解密字符串

《编程思维与实践》1048.解密字符串 题目 思路 主要到密码是升序的,所以先将每个数字对应的个数求出,之后升序排列输出即可得到结果. 求每个数字(0-9)对应的个数可以考虑每个英文单词中特有的字符(出现单次), zero,one,two,three,four,five,six,seven,eight,nine; 下面提供其中…

系统性能压力测试

系统性能压力测试 一、压力测试 压力测试是给软件不断加压&#xff0c;强制其在极限的情况下运行&#xff0c;观察它可以运行到何种程度&#xff0c;从而发现性能缺陷&#xff0c;是通过搭建与实际环境相似的测试环境&#xff0c;通过测试程序在同一时间内或某一段时间内&…

深度学习—卷积神经网络

卷积神经网络 传统意义上的多层神经网络只有输入层、隐藏层和输出层。其中隐藏层的层数根据需要而定&#xff0c;没有明确的理论推导来说明到底多少层合适。 卷积神经网络CNN&#xff0c;在原来多层神经网络的基础上&#xff0c;加入了更加有效的特征学习部分&#xff0c;具…

人生四维度

人生四维度 不是有钱了就成功&#xff0c;你知道&#xff1b;人生的成功不止一种&#xff0c;你也知道。但成功还有哪种&#xff1f;你知道吗&#xff1f; 如果把人生的体验展开&#xff0c;我们可以得到四个维度&#xff0c;高度、深度、宽度和温度。 财富、权力、影响力 构…

2023年3月股份行GX评测盘点:招商银行稳居榜首,各项指标均居前列

易观&#xff1a;2023 年3月GX评测数据显示&#xff0c;招商银行、平安口袋银行、中信银行位居行业Top 10&#xff0c;浦发银行、兴业银行、光大银行紧跟其后。 股份行APP 用户体验&#xff1a;招商银行以绝对优势稳居第一 2023年3月股份行GX评测结果数据显示&#xff0c;在操作…

VScode代码编辑器官网下载慢问题解决方法-亲测有效

VScode官网下载慢的问题如何解决&#xff1f; 问题描述&#xff1a; VisualStudioCode&#xff08;简称VSCode&#xff09;是Microsoft开发的一款功能强大的代码编辑器&#xff0c;它支持Windows&#xff0c;Linux和macOS等操作系统以及开源代码&#xff0c;因此被很多开发人…

maven从入门到精通 第四章 Maven中依赖的传递、排除、继承、聚合

这里写自定义目录标题 一 maven中依赖的传递1 依赖的传递性2 使用complie范围依赖spring-core3 测试依赖是否被传递4 依赖传递性的意义 二 maven中依赖的排除1 依赖排除概述2 具体操作依赖排除 三 maven中依赖的继承四 maven中依赖的聚合 一 maven中依赖的传递 1 依赖的传递性…

thinkphp+vue+html超市零食品美食推荐系统零食购物商城网站7v281

本系统的开发使获取食品推荐系统信息能够更加方便快捷&#xff0c;同时也使食品推荐系统管理信息变的更加系统化、有序化。系统界面较友好&#xff0c;易于操作 运行环境:phpstudy/wamp/xammp等 开发语言&#xff1a;php 后端框架&#xff1a;Thinkphp5 前端框架&#xff1a;vu…

Linux入门2(常用命令)

Linux入门2 Linux常用命令快捷键基础命令文件查看命令文件编辑命令进程管理命令用户管理命令 Linux常用命令 快捷键 Ctrl Alt T打开终端 Ctrl shift 加号 终端字体放大 ctrl 减号 终端字体缩小 基础命令 sudo su 进入管理员目录 exit 返回到用户目录 ls 当前目录下的文…

数据导向下制造业的生产效率、交易效率提升办法

在智能制造和工业4.0成为趋势的今天&#xff0c;大部分制造业企业&#xff0c;均已在企业内部通过实施PLM系统&#xff08;Product Lifecycle Management&#xff0c;产品生命周期管理系统&#xff09;&#xff0c;实现了对组织内产品研发过程和产品研发数据的管理&#xff0c;…

联发科MT8768核心板 安卓4G核心板智能模块MTK方案主板开发板

MT8768核心板是一款性能优异的芯片板&#xff0c;具有以下特点&#xff1a; 处理器方面&#xff0c;MT8768核心板采用联发科MTK8768平台&#xff0c;搭载八核A53处理器&#xff0c;最高主频可达2.3GHz&#xff0c;为您提供出色的运行速度和高效率。 内存和存储方面&#xff0c;…

OAK相机如何将 YOLO NAS 模型转换成blob格式?

编辑&#xff1a;OAK中国 首发&#xff1a;oakchina.cn 喜欢的话&#xff0c;请多多&#x1f44d;⭐️✍ 内容可能会不定期更新&#xff0c;官网内容都是最新的&#xff0c;请查看首发地址链接。 ▌前言 Hello&#xff0c;大家好&#xff0c;这里是OAK中国&#xff0c;我是助手…

数据库迁移同步 | 两地三中心到异地双活演变及关键技术探讨

两地三中心和异地多活都是分布式系统的关键技术&#xff0c;用于保证系统的高可用性和容错性。其中最关键的技术无疑是数据同步、同步防环和数据冲突解决。 异地容灾 & 两地三中心 两地三中心架构是一种分布式系统的架构模式&#xff0c;用于保证系统的高可用性和容错性。…

pom文件的project标签报错java.lang.OutOfMemoryError: GC overhead limit exceeded

1、pom文件的project标签报错java.lang.OutOfMemoryError: GC overhead limit exceeded&#xff0c;如何解决&#xff1f; 只需修改idea配置 调大内存&#xff0c;即可解决

git之gitk命令介绍

Gitk 是 Git 提供的一个 GUI 工具&#xff0c;可作为git图形化客户端使用。安装 Git 的时候会自动安装 Gitk 工具。打开git bash&#xff0c;输入 gitk 命令即可打开gitk工具。 Gitk 的主界面主要包含五个部分&#xff1a; 主菜单栏显示区提交信息显示区&#xff0c;显示提交…