数据结构:链表经典算法OJ题

news2024/9/20 14:44:41

目录

前言

一、移除链表元素

二、反转链表

三、合并两个有序链表

四、链表的中间节点

五、环形链表的约瑟夫问题


前言

    在了解了链表的相关知识后,我们还需要一些题目进行练习加深对链表这方面知识的理解,也可以用来检测链表这块学的的怎么样,废话不多说,开始上手。

一、移除链表元素

    这里给上题目链接感兴趣的可以看一下(移除链表元素),

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回新的头节点 。

 看题目描述,我们需要删除链表中链表节点为特定值的节点。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeElements(struct ListNode* head, int val) {
   struct ListNode*a=NULL;
   struct ListNode*b=NULL;
   if(head==NULL)
     return head;
    while(head)
    {
        if(head->val!=val)
        {
            if(a==NULL)
              a=b=head;
            else
            {
                b->next=head;
                b=b->next;
            }
        }
        
        head=head->next;
    }
    if(b)
         b->next=NULL;
    return a;
}

    首先,如果链表本身为空,就可以直接返回一个空指针,如果不为空就可以开始下一个阶段,先创建两个指针a,b指向开始给的头结点,让初始头结点开始遍历,如果遇到节点值为特定值就让b节点指向初始头结点的下一个,相当于跳过了这个节点,最后遍历完,如果b节点不为空,就将b的下一个节点置空,相当于是把那些带有特定值的节点删除了。

二、反转链表

    这里先给上题目链接(反转链表)

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

这里先给上代码,慢慢来讲解一下。 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* reverseList(struct ListNode* head) {
   
    if(head==NULL)
      return head;
 struct ListNode*n1=NULL;
    struct ListNode*n2=head;
    struct ListNode*n3=head->next;
    while(n2)
    {
        n2->next=n1;
        n1=n2;
        n2=n3;
        if(n3)
          n3=n3->next;
    }
    return n1;
}

     首先还是要判断链表是否为空,空链表直接返回就行了,这里需要创建三个指针,在遍历链表时,将当前节点的 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;
    if(list2==NULL)
      return list1;
    struct ListNode*n1=(struct ListNode*)malloc(sizeof(struct ListNode));
    struct ListNode*n2=n1;
    while(list1&&list2)
    {
        if(list1->val<=list2->val)
        {
            n2->next=list1;
            list1=list1->next;
            n2=n2->next;
        }
        else
        {
            n2->next=list2;
            list2=list2->next;
            n2=n2->next;
        }
    }
    if(list1)
      n2->next=list1;
    if(list2)
      n2->next=list2;
    struct ListNode*c=n1->next;
    free(n1);
    n1=NULL;
    return c;
}

 首先判断两个有序链表中是否有空链表,如果有一方为空链表,就可以直接返回另一个链表了,需要开辟一个新的链表,将两个链表的每一个值一一比较排个序,再一个一个的放入新的链表当中。

四、链表的中间节点

    题目链接(链表的中间节点)

给你单链表的头结点 head ,请你找出并返回链表的中间结点。

如果有两个中间结点,则返回第二个中间结点。

 这道题可以用很多种方式写出来,这里用的是快慢指针的方式,还有计数器法等方式(计数器法就是先遍历一遍链表算出有多少个节点,再除以二,按照除后的数字在遍历一遍到中间节点位子),这里快慢指针法就先上代码,后面讲解。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* middleNode(struct ListNode* head) {
    struct ListNode*a=head;
    int i=0;
    while(head)
    {
        head=head->next;
        i++;
    }
    int count=i/2;
    while(count>0)
    {
        a=a->next;
        count--;
    }
    return a;
}

让俩个指针开始时同时指向头结点,一个一次走一步,一个每次走两步,在快指针到达尾节点或者空节点时(奇数节点链表和偶数节点链表会不一样),慢指针就会在中间节点的位置(奇数节点指针会在中间节点,偶数节点指针会在中间两个节点的后一个节点),最后输出慢指针就行了。

五、环形链表的约瑟夫问题

     题目链接(约瑟夫问题)

描述

编号为 1 到 n 的 n 个人围成一圈。从编号为 1 的人开始报数,报到 m 的人离开。

下一个人继续从 1 开始报数。

n-1 轮结束以后,只剩下一个人,问最后留下的这个人编号是多少?

示例

输入:
5,2     
返回值:
3    
说明:
开始5个人 1,2,3,4,5 ,从1开始报数,1->1,2->2编号为2的人离开
1,3,4,5,从3开始报数,3->1,4->2编号为4的人离开
1,3,5,从5开始报数,5->1,1->2编号为1的人离开
3,5,从3开始报数,3->1,5->2编号为5的人离开
最后留下人的编号是3 

 先上代码,后面慢慢讲解。


 #include<stdlib.h>
 #include<stdio.h>
typedef struct music
{
    int data;
    struct music* next;
}music;
music*initial(int n)
{
    music*a=(music*)malloc(sizeof(music));
    a->data=n;
    a->next=NULL;
    return a;
}
music*creat(int n)
{
    music*a=initial(1);
    music*b=a;
    for(int i=2;i<=n;i++)
    {
        b->next=initial(i);
        b=b->next;
    }
    b->next=a;
    return b;
}
int ysf(int n, int m ) {
    music*a=creat(n);
    music*head=a->next;
    int count=1;
    while(head->next!=head)
    {
        if(count==m)
        {
            a->next=head->next;
            free(head);
            head=a->next;
            count=1;
        }
        else
        {
            a=head;
            head=head->next;
            count++;
        }
    }
    return head->data;
}

    这道题涉及到了链表的创建,所以就需要一个包含数据成员的结构体以及初始化函数和创建链表相关函数,在实现约瑟夫问题的函数中,先创建head和a指针,head指针就是扮演着正在报数的那个人,a这是head的前一个节点,当报数的head报道特定的数字,a就会跳过这个节点,然后再把这个节点释放掉,head继续在a->next,循环着操作,留下最后一个就可以输出结果了。


    本篇内容就到这里了,没到题目都给了链接,可以自己去尝试解题,光听的话效果没那么好。

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

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

相关文章

【手撕数据结构】二叉树和堆

目录 树的概念树的相关概念二叉树二叉树的概念满二叉树和完全二叉树 堆的概念与结构堆的向上调整算法思路分析代码详细解说 堆的向下调整算法算法图解分析代码详解分析 堆的各个接口堆的定义及声明堆的初始化堆的销毁堆的插入堆的删除取堆顶数据堆的数据个数堆的判空 树的概念 …

【CVE-2024-38077】核弹级Windows RCE漏洞如何自检并修复该漏洞(附批量漏洞检测工具及分析伪代码)

代码详细分析点击此处 # 伪代码分析链接 工具为官方工具&#xff0c;师傅可自行测试 深信服CVE-2024-38077漏洞扫描工具.exe Algorithm : SHA1Hash : 85ECBDB053950A20B9748E867586D059AAA19115Algorithm : SHA256Hash : 1BF3A372F95C4F5B2D776C6ABB1E9BCA51933C3…

机器学习·L3W2-协同过滤

推荐算法 推荐算法可以预测用户评分&#xff0c;并根据评分推荐数据 推荐算法与其他预测算法的区别在于&#xff1a;推荐算法中的数据大多都不完整&#xff0c;用户只对几个电影评分&#xff1b;而预测算法则要求数据完整&#xff0c;便于拟合和预测 协同过滤 评分矩阵Y&#x…

Install pytorch 使用 torch 的例子

如果不知道怎么开始和安装软件 从这里开始 如果需要GPU版本&#xff0c;请选择CUDA&#xff0c;而不是CPU PyTorchhttps://pytorch.org/ Python 3.8.13 | packaged by conda-forge | (default, Mar 25 2022, 06:04:10) [GCC 10.3.0] on linux Type "help", &quo…

k8s环境使用cronjob对mysql8进行备份

一、configmap 数据库备份脚本写入k8s环境的configmap文件&#xff0c;并生成config。 # cat mysql-back-configmap.yaml apiVersion: v1 kind: ConfigMap metadata:name: mysql8backnamespace: crontabs data:mysql8back.sh: |#!/bin/bashDUMPDIR/tmp#backupbackupDatedate…

【专题】2023-2024跨境旅游消费趋势研究报告合集PDF分享(附原数据表)

原文链接&#xff1a;https://tecdat.cn/?p37306 近日&#xff0c;“世界旅游联盟中欧旅游对话”在匈牙利布达佩斯举办&#xff0c;发布《2023 - 2024 跨境旅游消费趋势研究报告》。 报告显示&#xff0c;2023 - 2024 年全球旅游业复苏&#xff0c;跨境旅游人数和支出显著增加…

【Material-UI】Checkbox组件:Indeterminate状态详解

文章目录 一、什么是Indeterminate状态&#xff1f;二、Indeterminate状态的实现1. 基本用法示例2. 代码解析3. Indeterminate状态的应用场景 三、Indeterminate状态的UI与可访问性1. 无障碍设计2. 用户体验优化 四、Indeterminate状态的最佳实践1. 状态同步2. 优化性能3. 提供…

SQL Zoo 10.Window functions

以下数据均来自SQL Zoo 1.Show the lastName, party and votes for the constituency S14000024 in 2017.&#xff08;显示2017年选区“S14000024”的姓氏、政党和选票&#xff09; SELECT lastName, party, votesFROM geWHERE constituency S14000024 AND yr 2017 ORDER BY…

多个IT系统数据同步方案-操作标识

这是一个很普遍的方案&#xff0c;实现多个IT系统数据同步&#xff1a; 从上游发出的数据标识&#xff0c;就可以完整的控制数据&#xff0c;当然对上游的要求也多一些&#xff0c;就是打数据标识前一定要读取一下现有的数据。

Spring Boot 基于 SCRAM 认证集成 Kafka 的详解

一、说明 在现代微服务架构中&#xff0c;Kafka 作为消息中间件被广泛使用&#xff0c;而安全性则是其中的一个关键因素。在本篇文章中&#xff0c;我们将探讨如何在 Spring Boot 应用中集成 Kafka 并使用 SCRAM 认证机制进行安全连接&#xff1b;并实现动态创建账号、ACL 权限…

Android Studio生成系统签名platform.jks

准备工作&#xff1a; 系统工程师需要提供以下文件并且在同一个目录文件夹下面 1、platform.pk8 2、platform.x509.pem 3、signapk.jar(通用的) 按照以下顺序执行 1、platform.pk8和platform.x509.pem 生成 .jks 提供platform.pk8、platform.x509.pem 、signapk.jar&…

低代码革命:重塑开发效率与质量的未来

1. 引言 随着信息技术的快速发展&#xff0c;企业对应用程序的需求日益增长。然而&#xff0c;传统的软件开发模式面临着开发周期长、成本高、人才短缺等问题。近年来&#xff0c;“低代码”开发平台如雨后春笋般涌现&#xff0c;承诺让非专业人士也能快速构建应用程序。这种新…

Netty原理及高性能

1. Netty原理 Netty是一个基于Java的异步事件驱动的网络应用框架&#xff0c;他用于快速开发高性能、高可靠性的网络服务器和客户端应用。Netty的原理涉及多个方面&#xff0c;包括 Reactor模式、核心组件、编解码、线程模型以及TCP粘包和拆包处理等。 1.1 Reactor模式 Reactor…

玻璃存储还没整明白,陶瓷纳米存储又来了!

关注我们 - 数字罗塞塔计划 - 在信息爆炸的当下&#xff0c;我们每天产生的数据比以往任何时候都多。其实很多数据都是存储后很少被访问&#xff0c;但仍需要长期保存的“冷数据”。磁带、硬磁盘、光盘等传统存储介质难以提供冷数据存储所需的超长寿命、超大容量和持续可访问性…

Docker Compse单机编排

一.Docker Compse 介绍 Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。通过 Compose&#xff0c;你可以使用 YAML 文件来配置应用程序的服务、网络和卷&#xff0c;然后使用单个命令创建和启动所有服务。这使得在开发、测试和部署过程中管理多容器应用程…

精彩分享|暴雨亮相第二十届智能计算国际会议(ICIC 2024)

8月6日至8日&#xff0c;第二十届智能计算国际会议&#xff08;ICIC 2024&#xff09;在天津盛大召开&#xff0c;这场由宁波东方理工大学&#xff08;暂名&#xff09;主办&#xff0c;天津科技大学承办&#xff0c;中国矿业大学&#xff08;北京&#xff09;、中国矿业大学和…

【学习笔记】Matlab和python双语言的学习(非线性规划法)

文章目录 前言一、非线性规划法二、例题&#xff1a;选址问题1.确定决策变量2.确定约束条件3.确定目标函数4.建立模型5.求解 三、代码实现----Matlab1.Matlab 的 fmincon 函数&#xff08;1&#xff09;基本用法&#xff08;2&#xff09;简单示例 2.Matlab 代码第一问&#xf…

RegNet 图像识别网络,手写阿拉伯数字的图像分类

1、RegNet 网络介绍 regnet 是一个深度学习模型架构&#xff0c;用于图像分类任务。它是由 Facebook AI Research&#xff08;FAIR&#xff09;提出的&#xff0c;旨在实现高效的网络设计。regnet 通过在不同的网络层级上增加网络宽度和深度来提高模型性能。 regnet 的设计思…

如何使用 AWS CLI 创建和运行 EMR 集群

为初学者提供清晰易懂的教程 为初学者提供清晰易懂的教程 Apache Spark 和 AWS EMR 上的 Spark 集群 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 欢迎来到雲闪世界。Spark 被认为是“大数据丛林之王”&#xff0c;在数据分析、机器学习、流媒体和图形…

DataWhale AI夏令营第四期-魔搭生图task1学习笔记

根据教程提供的链接&#xff0c;进入相应文章了解魔搭生图的主要工作是通过对大量图片的训练&#xff0c;生成自己的模型&#xff0c;然后使用不同的正向、反向提示词使模型输出对应的图片 1.官方跑baseline教程链接:Task 1 从零入门AI生图原理&实践 2.简单列举一下赛事的…