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

牛客网题目

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. 总结

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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Qt Creator创建项目

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 使用Qt Creator创建项目 收录于专栏【Qt开发】 本专栏旨在分享学习Qt的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 温馨提示: 1. 新…

基于SpringBoot+Vue的非物质文化遗产保护与传播系统设计实现(地图组件)

&#x1f388;系统亮点&#xff1a;地图组件&#xff1b; 一.系统开发工具与环境搭建 1.系统设计开发工具 后端使用Java编程语言的Spring boot框架 项目架构&#xff1a;B/S架构 运行环境&#xff1a;win10/win11、jdk17 前端&#xff1a; 技术&#xff1a;框架Vue.js&#x…

C/C++进阶(一)--内存管理

更多精彩内容..... &#x1f389;❤️播主の主页✨&#x1f618; Stark、-CSDN博客 本文所在专栏&#xff1a; 学习专栏C语言_Stark、的博客-CSDN博客 其它专栏&#xff1a; 数据结构与算法_Stark、的博客-CSDN博客 ​​​​​​项目实战C系列_Stark、的博客-CSDN博客 座右铭&a…

RDD优化:缓存和checkpoint机制、数据共享(广播变量、累加器)、RDD的依赖关系、shuffle过程、并行度说明

文章目录 1. 缓存和checkpoint机制1.1 缓存使用1.2 checkpoint1.3 缓存和checkpoint的区别 2. 数据共享2.1 广播变量2.2 累加器 3. RDD依赖关系4.shuffle过程4.1 shuffle介绍4.2 spark计算要尽量避免shuffle 5. 并行度 1. 缓存和checkpoint机制 缓存和checkpoint也叫作rdd的持…

Springboot 整合 Java DL4J 实现企业门禁人脸识别系统

&#x1f9d1; 博主简介&#xff1a;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编程&#xff0c;…

vue后台管理系统从0到1(3)element plus 的三种导入方式

文章目录 vue后台管理系统从0到1&#xff08;3&#xff09;element plus 的三种导入方式element plus 引入方式完整引入按需导入手动导入 vue后台管理系统从0到1&#xff08;3&#xff09;element plus 的三种导入方式 element plus 引入方式 官方网址&#xff1a;https://el…

windows系统更新升级node指定版本【避坑篇!!!亲测有效】(附带各版本node下载链接)一定看到最后!不用删旧版!

Node.js 是一个开源、跨平台的 JavaScript 运行时环境&#xff0c;广泛应用于服务器端和网络应用的开发。随着 Node.js 版本的不断更新&#xff0c;我们可能需要升级到特定版本以满足项目需求或修复安全漏洞。又或者是学习开发另外一个新项目&#xff0c;新项目对Node版本要求更…

优达学城 Generative AI 课程2:Large Language Models (LLMs) Text Generation

建议先了解一下附录知识。 文章目录 1 官方课程内容自述Lesson 1: 大型语言模型&#xff08;LLMs&#xff09;简介Lesson 2: 自然语言处理&#xff08;NLP&#xff09;基础Lesson 3: Transformer 和注意力机制Lesson 4: 检索增强生成&#xff08;RAG&#xff09;Lesson 5: 为大…

查找企业联系电话的几种方法

在商业合作和销售拓展的过程中&#xff0c;找到企业的联系电话是至关重要的一步。无论是精准营销还是客户开发&#xff0c;拥有有效的联系方式可以大大提高成功率。那么&#xff0c;如何快速有效地查找企业联系电话呢&#xff1f;下面介绍几种常见的方法&#xff0c;以及如何借…

如何解决项目跟进中关键节点难以把控的问题?

在项目跟进的过程中&#xff0c;关键节点的把控常常是一个棘手的问题。如果不能有效地管理这些节点&#xff0c;项目可能会偏离轨道&#xff0c;导致延误、成本超支甚至失败。下面我们来分析一下都有哪些关键节点难以把控以及相应的应对策略。 1、需求变更节点 在项目进行中&a…

快速入门Tomcat服务(业务发布基础技能)

文章目录 1 Tomcat简介 2 安装tomcat 2.1 安装jdk 2.2 安装Tomcat 3 Tomcat目录结构 4 Tomcat重要配置文件 1 Tomcat简介 Tomcat是Sun公司官方推荐的Servlet和JSP容器&#xff0c;在中小型系统和并发访问用户不是很多的场合下&#xff0c;其作为轻量级应用服务…

无刷直流电机工作原理:【图文讲解】

电动机 (俗称马达) 是机械能与电能之间转换装置的通称。可以分为电动机和发电机.一般称电机时就是指电动机。这个在日常应用中&#xff0c;比较多见&#xff0c;比如机器人&#xff0c;手机&#xff0c;电动车等。 直流电机&#xff1a;分为有刷直流电机&#xff08;BDC&#…

HTTP的工作原理

HTTP&#xff08;Hypertext Transfer Protocol&#xff09;是一种用于在计算机网络上传输超文本数据的应用层协议。它是构成万维网的基础之一&#xff0c;被广泛用于万维网上的数据通信。&#xff08;超文本(Hypertext)是用超链接的方法&#xff0c;将各种不同空间的文字信息组…

【MySQL】CRUD增删改查操作

文章目录 CRUD简介一、Creat 新增1.单行数据全列插入2.单行数据全指定列插入3.多行数据指定列插入 二、Retrieve 检索1.全列查询 --练习阶段最简单的查询&#xff1a;&#xff08;在生产环境最好不要用&#xff01;&#xff01;&#xff09;2.指定列查询3.结果去重查询4.where条…

柒拾伍- AI内容农场生产文章自动发布至公众号 (一)

一、内容农场 X AI 看过很多的新闻说 AI 产生 内容 污染网络&#xff0c;我也想试一下到底能污染成怎样。 然后为了编写爆款的内容&#xff0c;我选用这个 内容农场 的种子是来源于 微博热搜&#xff0c;让生长出来的垃圾文章更加火爆 涉及内容不能放 二、编写代码 关于代…

常用类(一)----包装类的使用和分析

文章目录 1.包装类2.课堂测试题3.包装类方法4.Integer创建机制5.Integer面试题 1.包装类 概念&#xff1a;基本数据类型对应的类就是包装类&#xff0c;就是为了把基本数据类型转换为包装类&#xff0c;使用这个类里面的方法操作数据----装箱的过程&#xff1b; //装箱&#…

springboot查询全部部门流程

前端发送请求后&#xff0c;会请求DeptController的方法list()。 package com.intelligent_learning_aid_system.controller;import com.intelligent_learning_aid_system.pojo.Dept; import com.intelligent_learning_aid_system.pojo.Result; import com.intelligent_learni…

ArcGis JS天地图 暗色地图

方法一&#xff1a;使用css filter 在body下增加svg&#xff0c;并增加需要用到的滤镜&#xff0c;这边用到x-rays <svg id"svgfilters" aria-hidden"true" style"position: absolute; width: 0; height: 0; overflow: hidden"version"…

Kafka-初识

一、Kafka是什么&#xff1f; Kafka是一个高度可扩展、弹性、容错和安全的分布式流处理平台&#xff0c;由服务器和客户端组成&#xff0c;通过高性能TCP网络协议进行通信。它可以像消息队列一样生产和消费数据。可以部署在裸机硬件、虚拟机和容器上&#xff0c;也可以部署在本…

鼠标市场洞察:数据分析揭示消费趋势!

鼠标整体数据分析 一. 概述 本报告基于从淘宝商品搜索接口和淘宝精确月销量接口中提取的数据&#xff0c;分析了前百个品牌在销售额上的占比情况。分析涵盖了销售额和占比的数据&#xff0c;为决策提供了依据。(以上两个接口有需求的可以找我要链接&#xff09; 1. 大盘整体…