利用编程思维做题之反转链表

牛客网题目

1. 理解问题

        给到我们的是一个单链表的头节点 pHead,要求反转后,返回新链表的头节点。

         首先在心里设想能够快速理解的例子,如给你123序列,要你反转此序列如何回答?将最后一个数字3作为头,然后修改3后面跟着的数字为2,2后面的数字为1,这就是一个单链表的简单应用。需要提前考虑的问题:如何获取最后一个数字、遍历所有数值时需要区分前一个数值与后一个数值。

        单链表的特点是每个节点包含一个值和一个指向下一个节点的指针,因此反转链表的过程实际上是改变每个节点的指针方向。

2. 输入输出

  • 输入:单链表的头节点 pHead

  • 输出:反转后的链表的头节点。

3. 链表结构

        单链表的节点通常定义为:

struct ListNode {
    int val;               // 节点的值
    struct ListNode *next; // 指向下一个节点的指针
};

4. 制定策略

        我们可以使用迭代的方法反转链表,核心思想是通过遍历链表并逐个改变指针方向。以下是具体步骤:

  1. 初始化指针

    • prev指针: 表示前一个数值,可以用于追踪新链表的头节点,初始为 NULL

    • curr指针:表示当前数值,用于遍历链表,初始为 pHead

  2. 遍历链表

    • 在每次循环中,保存当前节点的下一个节点 nextTemp(按123的顺序遍历所有数值)

    • 将当前节点的 next 指针指向 prev(相当于反转操作,如1指向空、2指向1、3指向2)

    • 更新 prev 为当前节点 curr(将prev后移)

    • curr移动到下一个节点 nextTemp(curr后移)

  3. 返回新链表的头节点

    • curr 为空时,prev 就是新链表的头节点,即取到最后一个数值。

5. 实现代码

        以下是反转单链表的 C 语言关键函数实现:

struct ListNode {
    int val;
    struct ListNode *next;
};

struct ListNode* reverseList(struct ListNode* pHead) {
    struct ListNode* prev = NULL; // 上一个节点
    struct ListNode* curr = pHead; // 当前节点
    struct ListNode* nextTemp = NULL; // 下一个节点

    while (curr != NULL) {
        nextTemp = curr->next; // 保存下一个节点
        curr->next = prev;     // 反转当前节点的指针
        prev = curr;           // 移动 prev 到当前节点
        curr = nextTemp;       // 移动到下一个节点
    }

    return prev; // 返回新链表的头节点
}

5.1 完整c语言代码

#include <stdio.h>
#include <stdlib.h>

// 定义单链表节点结构
struct ListNode {
    int val;                // 节点的值
    struct ListNode *next;  // 指向下一个节点的指针
};

// 反转链表的函数
struct ListNode* reverseList(struct ListNode* pHead) {
    struct ListNode* prev = NULL; // 上一个节点
    struct ListNode* curr = pHead; // 当前节点
    struct ListNode* nextTemp = NULL; // 下一个节点

    // 遍历链表
    while (curr != NULL) {
        nextTemp = curr->next; // 保存下一个节点
        curr->next = prev;     // 反转当前节点的指针
        prev = curr;           // 更新 prev 为当前节点
        curr = nextTemp;       // 移动到下一个节点
    }

    return prev; // 返回新链表的头节点
}

// 创建新节点的辅助函数
struct ListNode* createNode(int value) {
    struct ListNode* newNode = (struct ListNode*)malloc(sizeof(struct ListNode));
    newNode->val = value;
    newNode->next = NULL;
    return newNode;
}

// 打印链表的辅助函数
void printList(struct ListNode* head) {
    struct ListNode* current = head;
    while (current != NULL) {
        printf("%d -> ", current->val);
        current = current->next;
    }
    printf("NULL\n");
}

// 测试代码
int main() {
    // 创建链表 {1 -> 2 -> 3}
    struct ListNode* head = createNode(1);
    head->next = createNode(2);
    head->next->next = createNode(3);

    printf("Original list:\n");
    printList(head); // 输出原链表

    // 反转链表
    struct ListNode* reversedHead = reverseList(head);

    printf("Reversed list:\n");
    printList(reversedHead); // 输出反转后的链表

    // 释放内存
    struct ListNode* temp;
    while (reversedHead != NULL) {
        temp = reversedHead;
        reversedHead = reversedHead->next;
        free(temp);
    }

    return 0;
}

5.2 代码说明
  1. 节点定义:定义了一个 ListNode 结构体,包含一个整型值和指向下一个节点的指针。

  2. 反转函数reverseList 函数通过迭代的方法反转链表,更新每个节点的指针。

  3. 辅助函数

    • createNode:用于创建新节点并返回节点指针。

    • printList:用于打印链表的内容,方便测试和调试。

  4. 主函数:在 main 函数中创建一个链表 {1 -> 2 -> 3},调用反转函数,并打印原链表和反转后的链表。

5.3 运行结果

        运行此代码时,您将看到原链表和反转后的链表的输出:

       Original list:
        1 -> 2 -> 3 -> NULL
        Reversed list:
        3 -> 2 -> 1 -> NULL

6. 时间和空间复杂度分析

  • 时间复杂度:O(n),因为我们遍历了链表一次。

  • 空间复杂度:O(1),只使用了常量级别的额外空间。

7. 总结

        通过上述步骤,培养我们理解题目、分析题目到解决题目的思维,确定解决方案且成功实现了代码。抽象出这种方法,它不仅适用于链表反转的问题,也可以推广到其他需要遍历和修改链表结构的情况。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

学习threejs,THREE.MeshBasicMaterial网格材质、THREE.MeshLambertMaterial漫反射材质

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.MeshBasicMaterial网…

MATLAB代码解析:利用DCGAN实现图像数据的生成

摘要 经典代码&#xff1a;利用DCGAN生成花朵 MATLAB官方其实给出了DCGAN生成花朵的示范代码&#xff0c;原文地址&#xff1a;训练生成对抗网络 (GAN) - MATLAB & Simulink - MathWorks 中国 先看看训练效果 训练1周期 训练11周期 训练56个周期 脚本文件 为了能让各位…

centos7 Oracle 11g rac 静默安装(NFS配置共享存储)

1.环境信息准备 注意&#xff1a; 在配置网络时&#xff0c;Oracle RAC的每个节点必须具有至少两个以上的网卡&#xff0c;一张网卡对外提供网络服务&#xff0c;另一张网卡用于各个节点间的通信和心跳检测等。在配置RAC集群的网卡时&#xff0c;如果节点1的公共接口是eth0&…

下一代安全:融合网络和物理策略以实现最佳保护

在当今快速发展的技术环境中&#xff0c;网络和物理安全融合变得比以往任何时候都更加重要。随着物联网 (IoT) 和工业物联网 (IIoT) 的兴起&#xff0c;组织在保护数字和物理资产方面面临着独特的挑战。 本文探讨了安全融合的概念、说明其重要性的实际事件以及整合网络和物理安…

本地装了个pytorch cuda

安装命令选择 pip install torch1.13.1cu116 torchvision0.14.1cu116 torchaudio0.13.1 --extra-index-url https://download.pytorch.org/whl/cu116 torch版本查看 python import torch print(torch.__version__) 查看pytorch能否使用cuda import torch# 检查CUDA是否可用…

鸿蒙NEXT开发-动画(基于最新api12稳定版)

注意&#xff1a;博主有个鸿蒙专栏&#xff0c;里面从上到下有关于鸿蒙next的教学文档&#xff0c;大家感兴趣可以学习下 如果大家觉得博主文章写的好的话&#xff0c;可以点下关注&#xff0c;博主会一直更新鸿蒙next相关知识 专栏地址: https://blog.csdn.net/qq_56760790/…

241014-绿联UGOSPro-通过虚拟机访问主机的用户目录及文件夹

如图所示&#xff0c;两种方式&#xff1b; 方式1: 通过Files中的Other Locations 添加主机ip&#xff0c;随后输入主机的用户名及密码即可系统及文件加载可能需要一段时间&#xff0c;有点卡&#xff0c;加载完应该就可以点击访问了 方式2: 通过命令行直接ssh/sftp userna…

【C++网络编程】(一)Linux平台下TCP客户/服务端程序

文章目录 Linux平台下TCP客户/服务端程序服务端客户端相关头文件介绍 Linux平台下TCP客户/服务端程序 图片来源&#xff1a;https://subingwen.cn/linux/socket/ 下面实现一个Linux平台下TCP客户/服务端程序&#xff1a;客户端向服务器发送&#xff1a;“你好&#xff0c;服务…

网络资源模板--Android Studio 实现简易新闻App

目录 一、项目演示 二、项目测试环境 三、项目详情 四、完整的项目源码 一、项目演示 网络资源模板--基于Android studio 实现的简易新闻App 二、项目测试环境 三、项目详情 登录页 用户输入&#xff1a; 提供账号和密码输入框&#xff0c;用户可以输入登录信息。支持“记…

[ComfyUI]Flux:国漫经典!斗破苍穹古熏儿之绮梦流光模型来袭

在数字艺术和创意领域&#xff0c;FLUX以其独特的虚实结合技术&#xff0c;已经成为艺术家和设计师们手中的利器。今天&#xff0c;我们激动地宣布&#xff0c;FLUX推出了一款全新的ComfyUI版本——Flux&#xff0c;它将国漫经典《斗破苍穹》中的古熏儿之绮梦流光模型完美融合&…

第十四章 RabbitMQ延迟消息之延迟队列

目录 一、引言 二、死信队列 三、核心代码实现 四、运行效果 五、总结 一、引言 什么是延迟消息&#xff1f; 发送者发送消息时指定一个时间&#xff0c;消费者不会立刻收到消息&#xff0c;而是在指定时间后收到消息。 什么是延迟任务&#xff1f; 设置在一定时间之后才…

Qt入门教程:创建我的第一个小程序

本章教程&#xff0c;主要介绍如何编写一个简单的QT小程序。主要是介绍创建项目的过程。 一、打开QT软件编辑器 这里使用的是QT5.14.2版本的&#xff0c;安装教程参考以往教程&#xff1a;https://blog.csdn.net/qq_19309473/article/details/142907096 二、创建项目 到这里&am…

使用Docker部署nextjs应用

最近使用nextjs网站开发&#xff0c;希望使用docker进行生产环境的部署&#xff0c;减少环境的依赖可重复部署操作。我采用的是Dockerfile编写应用镜像方式 docker-compose实现容器部署的功能。 Docker Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器…

【大模型问答测试】大模型问答测试脚本实现(第一版)

背景 公司已经做了一段时间的大模型&#xff0c;每次测试或者回归的时候都需要针对问答进行测试回归&#xff0c;耗费大量的时间与精力&#xff0c;因此结合产品特点&#xff0c;开发自动化脚本替代人工的操作&#xff0c;提升测试回归效率 设计 使用pythonrequestExcel进行…

Android笔记(二十四)基于Compose组件的MVVM模式和MVI模式的实现

仔细研究了一下MVI(Model-View-Intent)模式&#xff0c;发现它和MVVM模式非常的相识。在采用Android JetPack Compose组件下&#xff0c;MVI模式的实现和MVVM模式的实现非常的类似&#xff0c;都需要借助ViewModel实现业务逻辑和视图数据和状态的传递。在这篇文章中&#xff0c…

易我数据恢复软件,一键找回你的重要资料!

我们生活在数字时代&#xff0c;数据对我们来说超级重要。工作文件、学习资料&#xff0c;还有照片视频&#xff0c;这些东西要是没了或者不小心删了&#xff0c;那得多烦人啊。幸好现在科技发达&#xff0c;有了数据恢复软件&#xff0c;就像给我们数据上了一把安全锁。市面上…

一篇闪击常用放大器电路(学习笔记)

文章目录 声明概念名词经典电路分析反向放大器同向放大器加法器减法器积分电路微分电路差分放大电路电流->电压转换电路电压->电流转换电路 虚短与虚断一、虚短二、虚断 一些碎碎念 声明 ​ 本文是主要基于以下两篇博客所做的笔记&#xff1a; 模电四&#xff1a;基本放…

IT招聘乱象的全面分析

近年来&#xff0c;IT行业的招聘要求似乎越来越苛刻&#xff0c;甚至有些不切实际。许多企业在招聘时&#xff0c;不仅要求前端工程师具备UI设计能力&#xff0c;还希望后端工程师精通K8S服务器运维&#xff0c;更有甚至希望研发经理掌握所有前后端框架和最新开发技术。这种招聘…

MySQL基本语法、高级语法知识总结以及常用语法案例

MySQL基本语法总结 MySQL是一种广泛使用的关系型数据库管理系统&#xff0c;其基本语法涵盖了数据库和数据表的创建、查询、修改和删除等操作。 一、数据库操作 创建数据库&#xff08;CREATE DATABASE&#xff09; 语法&#xff1a;CREATE DATABASE [IF NOT EXISTS] databa…

最新PHP礼品卡回收商城 点卡回收系统源码_附教程

最新PHP礼品卡回收商城 点卡回收系统源码_附教程 各大电商平台优惠券秒杀拼团限时折扣回收商城带余额宝 1、余额宝理财 2、回收、提现、充值、新订单语音消息提醒功能 3、带在线客服 4、优惠券回收功能 源码下载&#xff1a;https://download.csdn.net/download/m0_66047…