顺序表和单链表的经典算法题
目录
前言
一、基础思想(数组)
1. 移除元素
2.删除有序元素的重复项
3.合并两个有序数组
二、单链表算法
1.移除链表元素
2.翻转链表
3.合并两个有序的链表
前言
Hello,小伙伴们,今天我们来做一个往期知识的回顾,今天我将为大家讲解几道经典的顺序表和单链表算法题,来帮助大家加深对单链表知识的讲解,同时带领大家来感受一下数据结构的魅力!
如果你喜欢我的内容的话,就请不要忘了点赞,评论和收藏,你的支持就是我更新的动力,万分感谢!!
好废话不多说,开始我们今天的正题。
一、基础思想(数组)
1. 移除元素
题目链接:https://leetcode.cn/problems/remove-element/description/
我们先看这道题假设我们现在一这样的一个数组:
要让我们清除掉所有 val = 3的值,我们想一想可以怎么做呢?
1.首先我们最容易想到的就是创建一个新的数组,然后遍历整个nums,将val != 4的值都放进
新的数组中,但是我们要注意题目中的条件,“你需要原地移除数字==val的值”
也就是说,我们不能开辟新的空间。所以这个方法行不通!
2.那我们可以试试这样的方法,我们首先创建两个整型变量,d1 ,d2 = 0;
初始的状态下,是这样的
我们让d1先走,当 nums[d1] != val时
nums[d2] = nums[d1];
d1++;
d2++;
然后再当nums[d1] == val时,直接跳过该元素,后面的元素会将其覆盖掉,或者是直接失去他的访问权限;
我们画图理解一下:
当nums[d1] == val时,d1直接跳过该元素,直到nums[d1] != val 或者 走到数组的末尾。
接下来直接直接拷贝到d2上:
d2++;
nums[d2] = nums[d1]
同理:最后我们就可以得到去除掉val的数组了,然后我们来实现一下这个代码:
int removeElement(int* nums, int numsSize, int val) {int dest = 0;int src = 0;for (int i = 0; i < numsSize; i++)//遍历数组{if (nums[src] == val)//排除指定的元素{src++;}else//计数{nums[dest] = nums[src];dest++;src++; }}return dest;
}
测试结果:下面是我根据这个思路对代码进行优化的结果,感兴趣的小伙伴一定要勇于挑战自己啊!!
2.删除有序元素的重复项
题目链接:https://leetcode.cn/problems/remove-duplicates-from-sorted-array/description/
这样的题,遇到了,我们能想出什么样的思路能?
假设我们有这样的一个 数组:
想要在题目中的条件下删除所有的重复项元素,我们能怎么办呢?
有了上一道题的基础,我们不 难想到,先创建两个整型变量:
int d1 = 0; int d2 = 0;
我们让d1先加1
再比对nums[d1]与nums[d2];
不相等则 nums[++d2] = num[d1],然后 d1++,直到整个循环备d1遍历一遍!
好,接下来我们来实现一下代码:
int removeDuplicates(int* nums, int numsSize) {int dest = 0;int src = 1;while (src < numsSize){if (nums[dest] != nums[src] && ++dest != src) {
//++dest != src 可以避免相等项的重复赋值!! 提高效率nums[dest] = nums[src];}src++;}return dest + 1;}
代码测试:
3.合并两个有序数组
题目链接:https://leetcode.cn/problems/merge-sorted-array/description/
这道题非常的有意思:
假设我们得到这两个数组:
要注意最后的数组是,经过nums1修改后得到的,返回的数组也是nums1,不能开辟新的空间!!!
我们可以试试这样的思路:
当 n and m都不小于0的时候,我们让nums1[n - 1] 与nums2[m - 1]比较大小
大的就放到nums1的末尾:
如图所示:
在 m 小于0之前,一直循环遍历
所以·我们实现代码为:
void merge(int *nums1, int n, int* nums2, int m)
{int l1 = m - 1;int l2 = n - 1;int l3 = m + n - 1;while (l1 >= 0 && l2 >= 0){if (nums1[l1] > nums2[l2]){nums1[l3--] = nums1[l1--];}else{nums1[l3--] = nums2[l2--];}}while (l2 >= 0){nums1[l3--] = nums2[l2--];}}
代码测试:
二、单链表算法
如果还不了解单链表的同学可以先去我的另一篇博客看看单链表的知识,这对数据结构的学习有很大的帮助!!
链接:http://t.csdnimg.cn/wS03W
1.移除链表元素
题目链接:https://leetcode.cn/problems/remove-linked-list-elements/description/
这样的题我们能相处什么样的思路呢?
也许我们可以试试这样解决问题:
再通过比对节点中存储的数据,若不要删除的节点的数据,就直接尾插:
否则直接跳过:
在最后一定要将newtail->next == NULL,否则新链表依然会包含后面需要被删除的节点!!
接下来,我们来实现一下代码:
typedef struct ListNode ListNode;
struct ListNode* removeElements(struct ListNode* head, int val) {ListNode* newhead = NULL;ListNode* newtail = NULL;newhead = newtail = (ListNode*)malloc(sizeof(ListNode));ListNode* pcur = head;while (pcur){if (pcur->val != val){newtail->next = pcur;newtail = newtail->next;}pcur = pcur->next;}newtail->next = NULL;ListNode* ret = newhead->next;
//最后要将哨兵位释放掉, 避免空间的浪费!!!free(newhead);newhead = NULL;return ret;
}
代码测试1:
2.翻转链表
题目链接:https://leetcode.cn/problems/reverse-linked-list/description/
这样的题我们能用什么样的思路来写呢?
这里作者菌,就为大家实现两种思路:
1.头插原链表
什么意思呢?我们画图来理解一下:
这样是不是就十分的清楚了:
接下来我们就可以直接来实现代码了:
typedef struct ListNode LN;
LN* reverseList(struct ListNode* head) {//思路1:头插原链表LN* n1, *n2;n1 = n2 = head;if (head == NULL)//这里一定要注意处理空指针的情况,也就是实例三return NULL;LN* pcur = head->next;while (pcur){LN* temp = pcur->next;pcur->next = n1;n1 = pcur;pcur = temp;}n2->next = NULL;return n1;
}
代码测试:
接下来,我们再来学习下一个思路:
这个思路我们就直接在原链表的基础上修改指针的指向:
我们先创建三个指针:
n1 n2 n3,他们分别指向不同的位置,如图:
有了大致的思路,我们接下来要解决一些,细节性的问题:
1.三个指针到最后,哪一个指针才能成为成为最后修改后链表的头结点?
2.三指针会出现位移差,所以要注意,不要出现对NULL的解引用操作!!!
接下来我们可以来实现代码了:
LN* n1, *n2, *n3;n1 = NULL;n2 = head;if (head == NULL)//还是要注意对NULL的处理!!return NULL;n3 = head->next;while (n2){n2->next = n1;n1 = n2;n2 = n3;if (n3)//n3会最先走到空,为了防止出现对NULL的解引用,我们要添加这一步n3 = n3->next;}return n1;
}
代码测试:
3.合并两个有序的链表
题目链接:https://leetcode.cn/problems/merge-two-sorted-lists/description/
这道题和我们上面的合并两个有序数组有异曲同工之妙。
我们还是可以用上面的数字比较,以此比较插入:
有了思路,我们实现代码就不难了:
typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {if (list1 == NULL)//首先处理NULL指针的情况return list2;if (list2 == NULL)return list1;if (list1 == NULL && list2 == NULL)return NULL;ListNode* newhead, *newtail;newhead = newtail = (ListNode*)malloc(sizeof(ListNode));while (list1 && list2){if (list1->val < list2->val){newtail->next = list1;newtail = newtail->next;list1 = list1->next;}else{newtail->next = list2;newtail = newtail->next;list2 = list2->next;}}while (list1){newtail->next = list1;list1 = list1->next;newtail = newtail->next;}while (list2){newtail->next = list2;list2 = list2->next;newtail = newtail->next;}
//注意尾节点的next指针一定要指向NULLnewtail->next = NULL;ListNode* ret = newhead->next;//释放哨兵位,以防空间浪费!!free(newhead);newhead = NULL;return ret;
}
代码测试:
好,今天的学习就到这里,我们下期再见,拜拜!!
相关文章:

顺序表和单链表的经典算法题
目录 前言 一、基础思想(数组) 1. 移除元素 2.删除有序元素的重复项 3.合并两个有序数组 二、单链表算法 1.移除链表元素 2.翻转链表 3.合并两个有序的链表 前言 Hello,小伙伴们,今天我们来做一个往期知识的回顾,今天我将…...
python基础知识点(蓝桥杯python科目个人复习计划71)
做些简单题 第一题:确定字符串是否包含唯一字符 题目描述: 实现一个算法来识别一个字符串的字符是否是唯一的。 若唯一输出YES,否则输出NO。 输入描述: 输入一个字符串,长度不超过100. 输出描述; 输出一行&…...
【大数据专题】Flink题库
1 . 简述什么是Apache Flink ? Apache Flink 是一个开源的基于流的有状态计算框架。它是分布式地执行的,具备低延迟、高吞吐的优秀性能,并且非常擅长处理有状态的复杂计算逻辑场景 2 . 简述Flink 的核心概念 ? Flink 的核心概念…...

Python鲁汶意外莱顿复杂图拓扑分解算法
🎯要点 🎯算法池化和最佳分区搜索:🖊网格搜索 | 🖊发现算法池 | 🖊返回指定图的最佳划分 | 🖊返回指定图的最佳分区 | 🎯适应度和聚类比较功能:🖊图的划分 |…...

【C++】类和对象之继承
目录 继承的概念和定义 继承的概念 继承的定义 继承的定义格式 继承关系和访问限定符 继承基类成员访问方式的变化 访问权限实例 基类和派生类对象赋值转换 继承中的作用域 派生类的默认成员函数 继承与友元 继承与静态成员 复杂的菱形继承及菱形虚拟继承 继承的…...

如何在LlamaIndex中使用RAG?
如何在LlamaIndex中使用RAG 什么是 Llama-Index LlamaIndex 是一个数据框架,用于帮助基于 LLM 的应用程序摄取、构建结构和访问私有或特定领域的数据。 如何使用 Llama-Index ? 基本用法是一个五步流程,将我们从原始、非结构化数据导向基于该数据生成…...

css气泡背景特效
css气泡背景特效https://www.bootstrapmb.com/item/14879 要创建一个CSS气泡背景特效,你可以使用CSS的伪元素(:before 和 :after)、border-radius 属性来创建圆形或椭圆形的“气泡”,以及background 和 animation 属性来设置背景…...

7.23模拟赛总结 [数据结构优化dp] + [神奇建图]
目录 复盘题解T2T4 复盘 浅复盘下吧… 7:40 开题 看 T1 ,起初以为和以前某道题有点像,子序列划分,注意到状态数很少,搜出来所有状态然后 dp,然后发现这个 T1 和那个毛关系没有 浏览了一下,感觉 T2 题面…...
MySQL-视 图
视 图 创建视图 视图是从一个或者几个基本表(或视图)导出的表。它与基 本表不同,是一个虚表。 语法: create view 视图名 【view_xxx/v_xxx】 说明: • view_name 自己定义的视图名; • as 后面是这…...
PHP SimpleXML
PHP SimpleXML PHP的SimpleXML扩展提供了一个非常方便的方式来处理XML数据。它是PHP内置的,因此不需要安装额外的库。SimpleXML可以将XML数据转换成对象,使得操作XML变得简单直观。本文将详细介绍SimpleXML的使用方法,包括加载XML、访问和修…...
【Spring Boot 自定义配置项详解】
文章目录 一、配置文件1. properties配置1.1 创建配置文件1.2 添加配置项1.3 在应用中使用配置项1.4 多环境配置 2. YAML配置2.1 创建配置文件2.2 添加配置项2.3 在应用中使用配置项2.4 多环境配置 二、自定义配置类1. 创建配置类2. 使用配置类 一、配置文件 Spring Boot支持多…...

电机相位接线错误导致的潜在问题
交流电机有两种基本类型:单相和三相。一般来说,单相交流电机通常用于家用电器等住宅应用,而三相交流电机则用于工业应用。这主要是因为大多数家庭使用单相电源,而大多数工业场所使用三相电源。 鉴于这两种不同的电源方案…...

react中如何mock数据
1.需求说明 因为前后端分离开发项目,就会存在前端静态页面写好了,后端数据接口还没写好;这时候前端就需要自己定义数据来使用。 定义数据有三种方式:直接写死数据、使用mock软件、json-server工具 这里讲解通过json-server工具…...
通过Faiss和DINOv2进行场景识别
目标:通过Faiss和DINOv2进行场景识别,确保输入的照片和注册的图片,保持内容一致。 MetaAI 通过开源 DINOv2,在计算机视觉领域取得了一个显着的里程碑,这是一个在包含1.42 亿张图像的令人印象深刻的数据集上训练的模型…...
新手入门基础Java
一:基础语法 1.Java的运行机制 2. Java基本语法 1.注释、标识符、关键字; 2.数据类型(四类八种) 3.类型转换 1.自动转换;2.强制转换; 4.常量和变量 1.常量;2.变量; 3.变量的作用域 5.运算符 1.算数运算符;2.赋值运算符;3.关系运算符; 4.逻辑运算符;5.自…...

2024最新版虚拟便携空调小程序源码 支持流量主切换空调型号
产品截图 部分源代码展示 urls.js Object.defineProperty(exports, "__esModule", {value: !0 }), exports.default ["9c5f1fa582bee88300ffb7e28dce8b68_3188_128_128.png", "E-116154b04e91de689fb1c4ae99266dff_960.svg", "573eee719…...

前端在浏览器总报错,且获取请求头中token的值为null
前端请求总是失败说受跨域请求影响,但前后端配置已经没有问题了,如下: package com.example.shop_manage_sys.config;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Conf…...

html+css前端作业 王者荣耀官网6个页面无js
htmlcss前端作业 王者荣耀官网6个页面无js 下载地址 https://download.csdn.net/download/qq_42431718/89571150 目录1 目录2 项目视频 王者荣耀6个页面(无js) 页面1 页面2 页面3 页面4 页面5 页面6...

在windows上使用Docker部署一个简易的web程序
使用Docker部署一个python的web服务🚀 由于是从事算法相关工作,之前在项目中,需要将写完的代码服务,部署在docker上,以此是开始接触了Docker这个工具,由于之前也没系统学习过,之后应该可能还会用…...
sqlalchemy使用mysql的json_extract函数查询JSON字段
sqlalchemy使用mysql的json_extract函数查询JSON字段 在SQLAlchemy中,如果你想要在MySQL中存储JSON字段,并且进行查询操作,可以按照以下步骤进行设置和查询: 1. 创建表格 首先,创建一个表格来存储包含JSON字段的数据。假设我们有一个名为 users 的表格,其中有一个名为…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
comfyui 工作流中 图生视频 如何增加视频的长度到5秒
comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗? 在ComfyUI中实现图生视频并延长到5秒,需要结合多个扩展和技巧。以下是完整解决方案: 核心工作流配置(24fps下5秒120帧) #mermaid-svg-yP…...