C语言题目练习3

news2025/1/9 18:55:44

这一篇博客也来看看和链表有关的题目~

反转链表

反转链表: https://leetcode.cn/problems/reverse-linked-list/description/
这个题目已经十分清晰了,那我们可以怎么做呢?
结合前面单链表的知识点,我们很容易可以想到第一个思路。

思路1

创建一个新链表,将原来的链表的结点进行头插

为了方便我们使用,我们同样将结点进行重命名

代码实现:

typedef  struct ListNode ListNode;
struct ListNode* reverseList(struct ListNode* head)
{
	//创建新链表
	ListNode* newHead = NULL;
	ListNode* newTail = NULL;

	//遍历原来的链表头插
	ListNode* pcur = head;
	while (pcur)
	{
		//如果新链表为空
		//头结点和尾结点就是当前的结点
		if (newHead == NULL)
		{
			newHead = newTail = pcur;
		}
		//新链表不为空进行头插
		else
		{
			//当前结点下一个节点指向新链表的头结点
			pcur->next = newHead;
			//当前结点成为新链表头结点
			newHead = pcur;
		}
		//继续遍历
		pcur = pcur->next;
	}
	//新链表尾结点的下一个结点置为空
	newTail->next = NULL;

	//返回新链表
	return newHead;
}

当我们写出代码提交的时候,它说运行时间超出限制

在OJ平台上不好看出问题我们使用VS进行调试一下去发现问题。

测试代码如下:


//测试问题代码
#include<stdio.h>
#include<stdlib.h>

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

typedef  struct ListNode ListNode;
struct ListNode* reverseList(struct ListNode* head)
{
    //特殊处理链表本来就为空
    if (head == NULL)
    {
    	return NULL;
    }
	//创建新链表
	ListNode* newHead = NULL;
	ListNode* newTail = NULL;

	//遍历原来的链表头插
	ListNode* pcur = head;
	//count记录进入循环几次
	int count = 0;
	while (pcur)
	{
		count++;
		//如果新链表为空
		//头结点和尾结点就是当前的结点
		if (newHead == NULL)
		{
			newHead = newTail = pcur;
		}
		//新链表不为空进行头插
		else
		{
			//当前结点下一个节点指向新链表的头结点
			pcur->next = newHead;
			//当前结点成为新链表头结点
			newHead = pcur;
		}
		//继续遍历
		pcur = pcur->next;
	}
	//新链表尾结点的下一个结点置为空
	newTail->next = NULL;

	//返回新链表
	return newHead;
}

void sListPrint(ListNode* head)
{
	ListNode* pcur = head;
	while (pcur)
	{
		printf("%d->", pcur->val);
		pcur = pcur->next;
	}
	printf("NULL\n");
}

int main()
{
	//手动创建链表
	ListNode* node1 = (ListNode*)malloc(sizeof(ListNode));
	ListNode* node2 = (ListNode*)malloc(sizeof(ListNode));
	ListNode* node3 = (ListNode*)malloc(sizeof(ListNode));
	ListNode* node4 = (ListNode*)malloc(sizeof(ListNode));

	node1->next = node2;
	node2->next = node3;
	node3->next = node4;
	node4->next = NULL;

	node1->val = 1;
	node2->val = 2;
	node3->val = 3;
	node4->val = 4;



	sListPrint(node1);
	ListNode* newList = reverseList(node1);
	sListPrint(newList);
	return 0;
}

我们会发现pcur和newHead一直在1和2之间循环,没有往后面走了,这是为什么呢?

事实上,在头插时使用pcur进行操作,已经改变了pcur的指向,pcur下一个结点永远是newHead,那么pcur也就走不到NULL,也就进入了死循环,这就是为什么刚刚代码超出时间限制,死循环了。

解决方案:使用一个结点pos保存pcur,pcur直接往后面走

正确代码(使用打印直观观察)


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

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

typedef  struct ListNode ListNode;
struct ListNode* reverseList(struct ListNode* head)
{
    //特殊处理链表本来就为空
    if (head == NULL)
    {
	    return NULL;
    }
	//创建新链表
	ListNode* newHead = NULL;
	ListNode* newTail = NULL;

	//遍历原来的链表头插
	ListNode* pcur = head;
	while (pcur)
	{

		//易错点
		//使用pos保存pcur
		//避免后面指向改变
		ListNode* pos = pcur;

		//pcur直接继续遍历
		pcur = pcur->next;

		//如果新链表为空
		//头结点和尾结点就是当前的结点
		if (newHead == NULL)
		{
			newHead = newTail = pos;
		}
		//新链表不为空进行头插
		else
		{
			//当前结点下一个节点指向新链表的头结点
			pos->next = newHead;
			//当前结点成为新链表头结点
			newHead = pos;
		}
	}
	//新链表尾结点的下一个结点置为空
	newTail->next = NULL;

	//返回新链表
	return newHead;
}

void sListPrint(ListNode* head)
{
	ListNode* pcur = head;
	while (pcur)
	{
		printf("%d->", pcur->val);
		pcur = pcur->next;
	}
	printf("NULL\n");
}

int main()
{
	//手动创建链表
	ListNode* node1 = (ListNode*)malloc(sizeof(ListNode));
	ListNode* node2 = (ListNode*)malloc(sizeof(ListNode));
	ListNode* node3 = (ListNode*)malloc(sizeof(ListNode));
	ListNode* node4 = (ListNode*)malloc(sizeof(ListNode));

	node1->next = node2;
	node2->next = node3;
	node3->next = node4;
	node4->next = NULL;

	node1->val = 1;
	node2->val = 2;
	node3->val = 3;
	node4->val = 4;

	

	sListPrint(node1);
	ListNode* newList = reverseList(node1);
	sListPrint(newList);
	return 0;
}

我们的代码是没有问题的,那么我们看看代码在OJ平台上是不是可以通过

提交通过~

那么有没有更加简单的方法呢?我们一起来看看思路2

思路2

1.创建三个指针n1、n2、n3

2.最开始n1指向NULL,n2指向head,n3指向n2的下一个结点

3.遍历链表,每一次进入循环n2的下一个结点指向n1

n1走到n2的位置,n2走到n3的位置,n3走到n3后面一个位置,直到n2为空结束循环。

这一个思路的好处在于没有创建新链表,直接在原来链表进行操作改变结点指向,是不是更加地巧妙呢!

代码实现:

 
typedef  struct ListNode ListNode;
struct ListNode* reverseList(struct ListNode* head)
{
	//特殊处理链表为空
	if (head == NULL)
	{
		return NULL;
	}
	//创建三个指针
	ListNode* n1, *n2, *n3;
	n1 = NULL;
	n2 = head;
	n3 = n2->next;

	ListNode* pcur = head;
	//遍历链表
	while (n2)
	{
		n2->next = n1;
		//n1、n2、n3往后面走
		n1 = n2;
		n2 = n3;
		if (n3)//n3先为空,判断一下避免对空指针解引用
			n3 = n3->next;
	}
	//返回链表
	return n1;
}

代码通过,这个方法更加巧妙,没有创建新链表,在原来链表改变指向就成功了。

今日练习结束,期待与各位未来的优秀程序员交流,有什么问题请私信~~~

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

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

相关文章

RTC -

RTC 目录 RTC 回顾 RTC 如何实现RTC制作一个时钟日历 代码编写 rtc.c完整代码 模块开发的步骤&#xff1a; 1、找文档 2、 在文档里面找通信方式&#xff0c;通信过程&#xff08;协议&#xff09; 3、代码> -- 前面学的是模块的开发&#xff0c;串口类&#xff0c;I…

决策树和集成学习的概念以及部分推导

一、决策树 1、概述 决策树是一种树形结构&#xff0c;树中每个内部节点表示一个特征上的判断&#xff0c;每个分支代表一个判断结果的输出&#xff0c;每个叶子节点代表一种分类结果 决策树的建立过程&#xff1a; 特征选择&#xff1a;选择有较强分类能力的特征决策树生成…

【论文阅读】SRCNN

学习资料 论文题目&#xff1a;Learning a Deep Convolutional Network for Image Super-Resolution&#xff08;学习深度卷积网络用于图像超分辨率&#xff09;论文地址&#xff1a;link.springer.com/content/pdf/10.1007/978-3-319-10593-2_13.pdf代码&#xff1a;作者提出的…

Java 一维数组作为函数参数

//一维数组的引用 #define SIZE 5 void input(int a[], int len); void output(int a[], int len);//函数的声明 int main(void) { int i 0; int arr[SIZE] { 86,85,85,896,45 };//同理五个数据只是偶然&#xff0c;可能会更多 //输入 input(arr, SIZE); …

目标检测系统操作说明【用户使用指南】(python+pyside6界面+系统源码+可训练的数据集+也完成的训练模型)

1.链接&#xff1a;上百种【基于YOLOv8/v10/v11的目标检测系统】目录&#xff08;pythonpyside6界面系统源码可训练的数据集也完成的训练模型&#xff09; 2.目标检测系统【环境搭建过程】&#xff08;GPU版本&#xff09; 3.目标检测系统【环境详细配置过程】&#xff08;CP…

241012-绿联UGOSPro-在仅无线WLAN网络条件下添加虚拟机网络

A. 新建NAT模式的虚拟子网 虚拟机-管理-网络管理-添加网络-如下设置 B. 虚拟机网络选择 C. 不同网络的对比 support.ugnas.com Virtio、e1000和rtl8139有什么区别&#xff0c;在创建虚拟机时&#xff0c;我应该如何选择&#xff1f; Virtio、e1000和rtl8139是三种不同的虚拟…

[论文阅读]SCOTT: Self-Consistent Chain-of-Thought Distillation

中文译名&#xff1a;SCOTT: 思维链一致性蒸馏 会议&#xff1a;Proceedings of the 61st Annual Meeting of the Association for Computational Linguistics (Volume 1: Long Papers) 链接&#xff1a;SCOTT: Self-Consistent Chain-of-Thought Distillation - ACL Antholo…

MySQL【知识改变命运】05

1&#xff1a;where的基本用法练习&#xff08;比较运算符&#xff09; 基本操作&#xff1a;查询英语<60的同学 如果english为NULL&#xff0c;会自动过滤掉&#xff0c;NULL比较特殊 查询语⽂成绩⾼于英语成绩的同学 这个过程&#xff1a;先读取表中每行记录&#xf…

18925 试卷排序(双向链表)

### 思路 1. **初始化队列**&#xff1a;将编号为1的试卷放入队列。 2. **依次插入试卷**&#xff1a;从第2张试卷开始&#xff0c;根据输入的x和p&#xff0c;将试卷插入到指定位置。 3. **输出结果**&#xff1a;输出最终的试卷序列。 ### 伪代码 function reorder_papers(…

计算机的错误计算(一百二十二)

摘要 讨论 的计算精度问题。 例1. 已知 计算 不妨在 Excel 的单元格中计算&#xff0c;则有&#xff1a; 若在Python下计算&#xff0c;则输出似乎更精确&#xff1a; 然而&#xff0c;16位有效数字的正确结果为 0.4999999999940000&#xff08;ISRealsoft 提供&#…

Matlab 多机器人编队数据分析

文章目录 前言一、Function quiver not supported for code generation.二、在仿真环境中添加障碍物三、simulink中function函数初始化五、在MATLAB中&#xff0c;实现在绘图时只删除上一次绘制的图形而不是整个图形界面六、matlab simulink中&#xff0c;程序不断发出机器人位…

git的学习使用(搭建本地仓库,创建本地仓库,配置本地仓库)(附带Ubuntu云服务器git安装流程)

学习目标&#xff1a; 学习使用git&#xff0c;并且熟悉git的使用 学习内容&#xff1a; 必备环境&#xff1a;xshell&#xff0c;Ubuntu云服务器 如下&#xff1a; 搭建 git 环境掌握 Java 基本语法掌握条件语句掌握循环语句 搭建git环境&#xff1a; 1、先检查自己的云服…

vscode的一些概念和原理,插件系统简单上手指南

VScode 技术栈和架构 使用的技术栈&#xff1a; Electron。Typescript。Node.js。Monaco Editor。 代码编辑器 主进程 (Main Process): 负责应用的生命周期管理、菜单、系统托盘等操作系统相关的功能。Electron 的主进程还负责启动渲染进程&#xff0c;并提供与 Node.js 之间…

Excel:多种方法实现1列转多列表格(含vba实现)

要求&#xff1a;将A列中的名字放到右边的表格里面 一、当数据较少的时候手动实现更快 实现的步骤&#xff1a; 1.先按照下面的方式填充右边的表格 然后选中a2、a7所在的前两行进行下拉填充 2.填充完毕表格的样子 3.选中该表格所在的区域 → 点击菜单栏“开始” → 查找 → 替…

python之selenium接管打开的谷歌浏览器窗口——隐藏爬虫特征,跳过登陆弹窗验证

文章目录 引言使用selenium接管打开的谷歌浏览器总结 引言 我们知道通过selenium打开的浏览器与本地电脑上打开的浏览器是不同的&#xff0c;selenium通过插件打开浏览器页面会显示爬虫特征信息&#xff0c;且在访问某些网站时&#xff0c;很容易被检测出是一个爬虫机器&#x…

第十五周:机器学习

目录 摘要 abstrct 一、HW3——食物图片分类CNN 二、GAN计算推导 1、引入 2、最大似然估计 3、divergence的计算 4、总结 三、GAN的架构——fGAN 1、f-divergence 2、共轭函数 3、connetction with GAN 总结 摘要 本周进一步学习了GAN基本原理&#xff0c;主…

element el-tree 自定义图标

除了自定义以外,下方代码还包含 tree自动展开 点击节点后节点聚焦 节点的click事件 节点查询 <template><el-inputplaceholder"请输入要查询的节点"v-model"filterText"clearable></el-input><el-treehighlight-currentclass&quo…

【RabbitMQ】RabbitMQ 的七种工作模式介绍

目录 1. Simple(简单模式) 2. Work Queue(工作队列) 3. Publish/Subscribe(发布/订阅) 4. Routing(路由模式) 5. Topics(通配符模式) 6. RPC(RPC通信) 7. Publisher Confirms(发布确认) 上一篇文章中我们简单认识了RabbitM1: 【RabbitMQ】RabbitMQ 的概念以及使用Rabb…

【Qt】窗口关闭提示框

在关闭QWdiget窗口时弹出提示框 重写**closeEvent**函数 void closeEvent(QCloseEvent* event) override;QMessageBox *msgBox new QMessageBox(QMessageBox::Question, "信息提示", "是否保存当前数据&#xff1f;", QMessageBox::Save | QMessageBox::N…

github克隆项目中的子模块submodule时遇到“无法访问远程仓库,请检查权限“

问题描述 在拉取仓库的时候发现了新东西。 仓库中有两个文件夹提示 点击之后&#xff0c;发现跳转到了另一个仓库 &#xff0c;原来这是仓库的子模块&#xff0c;第一次见&#xff0c;也就是仓库中包含了其他的的仓库&#xff0c;就是这么简单的原理。 但是在拉取仓库以后发现…