代码随想录Day03 | 链表基础1 LeetCode T203 移除链表元素 T707设计链表 T206 反转链表

本题思路和解答主要来源于:

代码随想录 (programmercarl.com)

LeetCode T203 移除链表元素

题目链接:203. 移除链表元素 - 力扣(LeetCode)

首先我们回顾一下单向链表,每个链表有一个指针域和一个数据域,在内存中是呈现不连续排列的,对比之前的数组,链表的查找的O(n)的是时间复杂度,因为链表需要一个一个的从头向后找,数组则是O(1)的时间复杂度,对于增添和删除元素,链表则只需要将待删除元素的前一个元素的指针指向后一个元素,是O(1)的时间复杂度,而对于数组则需要移动后面若干个元素,是O(n)的时间复杂度.

综上,我们得到了一条结论,在需要频繁查找而不需要频繁添加元素的集合里使用数组,反之使用链表. 

思路1:  直接删除元素

这里有两个经典的思路,一是分头节点和后面的节点来讨论,我们先说这种思路,首先处理头节点的val是我们查找的val,我们一定是使用while循环而不是if语句,因为这个查找是持续进行下去的,如果我的链表是1->1->1->1,且查找值也是1的话那么只有一个if语句就不能解决问题.

注:一定要记得判断节点不为空
 

while (head != null && head.val == val) {head = head.next;}

然后我们判断一下头结点是否为空,如果是,直接返回头结点,不是我们就继续往后走,注意,我们要定义两个指针来解决移除元素的工作,一个pre指针是记录当前指针的前一个节点,cur指针是临时创建出来保证head不被修改的,然后我们判断只要cur指针是否为空,如果不是空指针且值相等我们就进行移除操作,不是空指针且值不等我们就进行前进操作.最后返回head即可.

完整实现代码: 

while (head != null && head.val == val) {head = head.next;}if (head == null) {return head;}ListNode pre = head;ListNode cur = head.next;while (cur != null) {if (cur.val == val) {pre.next = cur.next;} else {pre = cur;}cur = cur.next;}return head;

思路2:使用虚拟头结点 

 这里我们还可以使用虚拟头结点,目的是统一移除操作,避免了额外来处理我们的头结点,我们也可以认为是常说的哨兵节点,这样我们可以统一从头结点出发,首先判断空链表,如果是就直接返回头节点,下面我们创建虚拟头结点dummy,让它的next指向头结点,创建一个cur节点指向head,pre指向dummy,只要cur不是空指针,我们就开始判断值,后面的操作同上,最后返回dummy的下一个节点.

实现代码 

public ListNode removeElements(ListNode head, int val) {if (head == null) {return head;}// 因为删除可能涉及到头节点,所以设置dummy节点,统一操作ListNode dummy = new ListNode(-1, head);ListNode pre = dummy;ListNode cur = head;while (cur != null) {if (cur.val == val) {pre.next = cur.next;} else {pre = cur;}cur = cur.next;}return dummy.next;
}

LeetCode T707: 设计链表

链接:707. 设计链表 - 力扣(LeetCode)

其实就是设计链表的增删查的一些基础接口,这里我们仍然延续上文的虚拟头节点方式进行书写代码.我们一个功能一个功能来实现.

1. 定义单链表

class ListNode {int val;ListNode next;ListNode(){}ListNode(int val) {this.val=val;}
}

2.初始化链表 

初始化之前,我们先定义两个变量:链表长度,链表的虚拟头结点.

 int size;ListNode dummyHead;
public MyLinkedList() {size = 0;dummyHead = new ListNode(0) ;     }

3.获取index下标的元素 

首先,判定index的合法性,如果index>size-1,那么直接返回-1,然后定义cur指针,指向虚拟头结点dummyHead,进行index+1次循环,找到目标元素,返回他的数据.至于为什么是index+1次,这里我们考虑极端情况,index = 0,这里我们需要进行一次循环,即cur = cur.next;

public int get(int index) {if(index>size-1){return -1;}ListNode cur = dummyHead;for(int i = 0;i<=index;i++){cur = cur.next;}return cur.val;}

4.在链表中间插入元素

因为题目要求有在链表末尾和头部插入元素,这里我们先实现在链表中间插入元素,后面前两个需求就迎刃而解了.

这里我们想再节点a和节点b中间加上一个节点c一定不能先让a节点的指针指向c节点,这样我们的b节点就找不到了,所以要让c节点先指向b节点,再用a节点指向c节点. 

public void addAtIndex(int index, int val) {if(index>size){return;}size++;ListNode pre = dummyHead;for(int i = 0;i<index;i++){pre = pre.next;}ListNode toAdd = new ListNode(val);toAdd.next = pre.next;pre.next = toAdd;}

 LeetCode T206 反转链表

链接:206. 反转链表 - 力扣(LeetCode)

思路1:双指针写法 

实质上我们就是让这个链表的指针对调一个方向

这里我们prev就是最后尾指针指向的NULL,所以初始化为NULL,这里temp是为了保存cur指针的下一个元素,不然在cur指针反转后变成尾指针之后就找不到cur原本指向的元素了. ,然后循环的终止条件就是cur不等于空指针,因为原来的尾节点指向空指针,当cur等于空指针的时候,prev就是我们所求的反转后的头指针.

// 双指针
class Solution {public ListNode reverseList(ListNode head) {ListNode prev = null;ListNode cur = head;ListNode temp = null;while (cur != null) {temp = cur.next;// 保存下一个节点cur.next = prev;prev = cur;cur = temp;}return prev;}
}

思路2: 递归写法

递归写法实际上是双指针写法的一种延伸

class Solution {public ListNode reverseList(ListNode head) {return reverse(null, head);}private ListNode reverse(ListNode prev, ListNode cur) {if (cur == null) {return prev;}ListNode temp = null;temp = cur.next;// 先保存下一个节点cur.next = prev;// 反转// 更新prev、cur位置// prev = cur;// cur = temp;return reverse(cur, temp);}
}

总结:

在进行循环分析的时候,一定要设置好足够的节点先保存待会会消失的节点,可以给一定的极端的例子来验证代码的可行性,考虑好空指针的判断和结束条件即可.

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

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

相关文章

水库河道生态流量监测系统的主要内容

一、系统背景 我国为保护河流生态环境&#xff0c;推动水资源科学、合理、有序开发和可持续利用&#xff0c;各地水利和环保部门相继出台措施对不满足生态流量下泄要求的水电站责令整改或挂牌督办。近几年几百家水库在各个主要流域建成&#xff0c;由于缺乏对各个水库生态下泄流…

win10系统x64安装java环境以及搭建自动化测试环境

记录一下卑微C低能选手安装java和环境配置&#xff1a; 一、java安装包下载 进入oracle的下载界面&#xff1a;Java Downloads | Oracle 下拉选择对应版本&#xff0c;一定要选择jdk安装包下载 注&#xff1a;这里下载必须要注册账号&#xff0c;下载速度还是非常快 二、开…

容器管理工具 Docker生态架构及部署

目录 一、Docker生态架构 1.1 Docker Containers Are Everywhere 1.2 生态架构 1.2.1 Docker Host 1.2.2 Docker daemon 1.2.3 Registry 1.2.4 Docker client 1.2.5 Image 1.2.6 Container 1.2.7 Docker Dashboard 1.3 Docker版本 二、Docker部署 2.1 使用YUM源部署…

vue3+vite 引用svg图标

页面展示效果&#xff1a; 1、安装依赖插件vite-plugin-svg-icons和fast-glob npm install vite-plugin-svg-icons --save npm install fast-glob --save 2、在vite.config.ts文件修改配置 import {createSvgIconsPlugin} from vite-plugin-svg-icons; createSvgIconsPlugin({…

3D 视觉市场空间广阔,3D 感知龙头全技术路线布局

3D 视觉市场尚处在发展早期,空间广阔 人类 70%以上信息通过眼睛获取,对于机器而言,视觉感知也是其“智能化”升级的重要基础。3D 成像让每一个像素除 x、y 轴数据外,还有 z 轴(深度/距离)数据。围绕着人体、物体、空间扫描一圈,就能得到点云图和精准的“1:1”还原的 3D …

colmap+openMVS稠密重建

简要记录一下colmapopenMVS稠密重建相关使用 openMVS的sample使用 测试数据集下载 链接&#xff1a;https://pan.baidu.com/s/13T04aKJ2OB6_RX7IMMGhpg 提取码&#xff1a;oxkp运行测试 将data放在OPENMVS/路径下。 cd ~/Documents/OPENMVS/openMVS/openMVS_build ./bin/Den…

【超详细Vue2教程】超详细的Vue2入门教程,让你的开发效率大大提高(自己整理的笔记,超详细!)

十一&#xff0c;Vue 声明&#xff1a;图片资源来自于黑马程序员公开学习资料 本人在学习当中&#xff0c;详细整理了笔记&#xff0c;供大家参考学习 11.1 Vue2 11.1.1 Vue简介 1-1 vue 框架的特性 // 数据驱动视图 // 双向数据绑定1-2 数据驱动视图 在使用了 vue 的页…

什么是内容运营?

关于内容运营&#xff0c;在不同种类的公司&#xff0c;侧重点也不一样。 电商平台的内容运营岗更偏内容营销&#xff1b;产品功能比较简单的公司&#xff0c;内容运营和新媒体运营的岗位职责差不多&#xff1b;而内容平台的内容运营更多的是做内容的管理和资源整合。

Selenium Web自动化测试 —— 高级控件交互方法!

一、使用场景 使用场景对应事件复制粘贴键盘事件拖动元素到某个位置鼠标事件鼠标悬停鼠标事件滚动到某个元素滚动事件使用触控笔点击触控笔事件&#xff08;了解即可&#xff09; https://www.selenium.dev/documentation/webdriver/actions_api 二、ActionChains解析 实例…

国庆中秋特辑(四)MySQL如何性能调优?上篇

MySQL 性能优化是一项关键的任务&#xff0c;可以提高数据库的运行速度和效率。以下是一些优化方法&#xff0c;包括具体代码和详细优化方案。 接下来详细介绍&#xff0c;共有10点&#xff0c;先介绍5点&#xff0c;下次再介绍其他5点 1. 优化 SQL 语句 1.1 创建索引 创建…

目标识别项目实战:基于Yolov7-LPRNet的动态车牌目标识别算法模型

目标识别项目&#xff1a;基于Yolov7-LPRNet的动态车牌目标识别算法模型(一) 前言 目标识别如今以及迭代了这么多年&#xff0c;普遍受大家认可和欢迎的目标识别框架就是YOLO了。按照官方描述&#xff0c;YOLOv8 是一个 SOTA 模型&#xff0c;它建立在以前 YOLO 版本的成功基…

本地电脑搭建SFTP服务器,并实现公网访问

本地电脑搭建SFTP服务器&#xff0c;并实现公网访问 文章目录 本地电脑搭建SFTP服务器&#xff0c;并实现公网访问1. 搭建SFTP服务器1.1 下载 freesshd 服务器软件1.3 启动SFTP服务1.4 添加用户1.5 保存所有配置 2. 安装SFTP客户端FileZilla测试2.1 配置一个本地SFTP站点2.2 内…

全网最全Python系列教程(非常详细)---字符串讲解(学Python入门必收藏)

&#x1f9e1;&#x1f9e1;&#x1f9e1;这篇是关于Python中字符串的讲解&#xff0c;涉及到以下内容&#xff0c;欢迎点赞和收藏&#xff0c;你点赞和收藏是我更新的动力&#x1f9e1;&#x1f9e1;&#x1f9e1; 本文将从以下几个方面展开对字符串的讲解&#xff1a; 1、字…

【数据结构】—超级详细的归并排序(含C语言实现)

​ 食用指南&#xff1a;本文在有C基础的情况下食用更佳 &#x1f525;这就不得不推荐此专栏了&#xff1a;C语言 ♈️今日夜电波&#xff1a;斜陽—ヨルシカ 0:30━━━━━━️&#x1f49f;──────── 3:20 …

1.物联网射频识别

1.RFID概念 RFID是Radio Frequency Identification的缩写&#xff0c;又称无线射频识别&#xff0c;是一种通信技术&#xff0c;可通过无线电讯号识别特定目标并读写相关数据&#xff0c;而无需与被识别物体建立机械或光学接触。 RFID&#xff08;Radio Frequency Identificati…

前端JavaScript入门到精通,javascript核心进阶ES6语法、API、js高级等基础知识和实战 —— Web APIs(二)

思维导图 一、事件监听&#xff08;绑定&#xff09; 1.1 事件监听 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name&q…

学物联网有前途吗?

学物联网有前途吗&#xff1f; 物联网即“万物相连的互联网”&#xff0c;是互联网基础上的延伸和扩展的网络&#xff0c;将各种信息传感设备与互联网结合起来而形成的一个巨大网络&#xff0c;实现在任何时间、任何地点&#xff0c;人、机、物的互联互通。最近很多小伙伴找我&…

这个国庆场景下的创意数据应用,体现了数字经济时代的商业价值

在生成式AI爆火的2023年&#xff0c;数据协作和数据交换的商业价值越来越明显。大模型的训练正需要海量跨领域数据的“投喂”&#xff0c;才能真正创造商业价值涌现的奇迹。而如何在保护数据安全的前提下&#xff0c;有效发挥数据资产的商业价值&#xff0c;成为企业数字化亟需…

钉钉自动打卡

钉钉自动打卡 1.准备2.测试3.修改4.效果 因为一系列原因&#xff0c;本人咸鱼50块钱淘了一个小米note移动4G&#xff0c;系统是MIUI6&#xff0c;因为版本太老了&#xff0c;所以不能设置自动开启应用&#xff0c;所以就用了adb,链接电脑&#xff0c;定时跑程序&#xff0c;按按…

SELinux 介绍

背景 在工作中经常需要在 android 中增加一些东西&#xff0c; 而android有自己的安全限制&#xff0c;如果不懂SELinux&#xff0c;就不好添加。 Control Access Model https://zh.wikipedia.org/wiki/Chmod https://linux.die.net/man/1/chcon DAC DAC and Trojan Horses D…