【Java算法题】剑指offer_01数据结构
前言
刷题链接:
https://www.nowcoder.com/exam/oj/ta?page=2&tpId=13&type=265
1. 链表
JZ24 反转链表
![[图片]](https://img-blog.csdnimg.cn/f5a5462a1c8e47fa8cb9a4335117eb3b.png)
思路:基本操作,如下所示。
![[图片]](https://img-blog.csdnimg.cn/b81f7fa9b1004bb9ae7d2d4b798c2479.png)
![[图片]](https://img-blog.csdnimg.cn/3f998eed13bb413fa5c89456c014e7a9.png)
![[图片]](https://img-blog.csdnimg.cn/682fe91bd13b46f98db8fa7da9f1c54f.png)
/*
public class ListNode {int val;ListNode next = null;ListNode(int val) {this.val = val;}
}*/
public class Solution {public ListNode ReverseList(ListNode head) {if(head == null){return null;}ListNode pre = null;ListNode cur = head;ListNode temp = null;while(cur != null){temp = cur.next;cur.next = pre;pre = cur;cur = temp;}return pre;}
}
JZ6 从尾到头打印链表
![[图片]](https://img-blog.csdnimg.cn/24ee344dff1e40919152392e9310565a.png)
思路:
- 反转链表
- 添加元素至数组
/**
* public class ListNode {
* int val;
* ListNode next = null;
*
* ListNode(int val) {
* this.val = val;
* }
* }
*
*/
import java.util.ArrayList;
public class Solution {public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {ArrayList<Integer> arr = new ArrayList<Integer>();// 1. 链表不为空,则反转链表if(listNode!=null){listNode = ReverseList(listNode);// 2. 添加元素到ArrayListListNode cur = listNode;while(cur!=null){arr.add(cur.val);cur = cur.next;}return arr;}return arr; // 空链表返回空ArrayList}public ListNode ReverseList(ListNode head){ //反转链表ListNode pre = null;ListNode cur = head;ListNode temp = cur.next;while(cur != null){temp = cur.next;cur.next = pre;pre = cur;cur = temp;}return pre;}
}
JZ25 合并两个排序的链表
![[图片]](https://img-blog.csdnimg.cn/fbfe53e080f142b29e6e02b05019cb82.png)
![[图片]](https://img-blog.csdnimg.cn/feac183e27ab49749c2831a539c40a2a.png)
思路:看代码很清楚,利用新的lsit存排序后的链表,小的先存。
/*
public class ListNode {int val;ListNode next = null;ListNode(int val) {this.val = val;}
}*/
public class Solution {public ListNode Merge(ListNode list1,ListNode list2) {ListNode list = new ListNode(0);ListNode l = list;if(list1 == null || list2 == null){return list1 != null?list1:list2;}while(list1!=null && list2!=null){if(list1.val<=list2.val){l.next = list1;list1=list1.next;}else{l.next = list2;list2=list2.next;}l=l.next;}if(list1!=null){l.next = list1; }if(list2!=null){l.next = list2;}return list.next;}
}
JZ52 两个链表的第一个公共节点
![[图片]](https://img-blog.csdnimg.cn/b13fa257ab474f8abaf6f68be84aaaaf.png)
![[图片]](https://img-blog.csdnimg.cn/63ecd9f3e02b47c4b5ddcdbb81b51714.png)
思路:Y字形链表,以相同的速度遍历两条链表最终总会相遇。(注意:当遍历链表1结束,将指针指向链表2的头。)
/*
public class ListNode {int val;ListNode next = null;ListNode(int val) {this.val = val;}
}*/
public class Solution {public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {ListNode p1=pHead1, p2=pHead2;while(p1!=p2){p1 = (p1==null)?pHead2:p1.next;p2 = (p2==null)?pHead1:p2.next;}return p1;}
}
JZ23 链表中环的入口结点
![[图片]](https://img-blog.csdnimg.cn/c6cd828e22f145919e88ad1f276fb7a8.png)
![[图片]](https://img-blog.csdnimg.cn/6d76930b5a7b47f0b00f6a614cc137a8.png)
思路:
快慢指针,快指针走两步,慢指针走一步。
![[图片]](https://img-blog.csdnimg.cn/e815dcdd81db433f85a0908bacf1b31f.png)
- 判断是否有环;
- 有环则将slow指针指向头,fast从相遇点出发,二者将在入环点相遇。
/*public class ListNode {int val;ListNode next = null;ListNode(int val) {this.val = val;}
}
*/
public class Solution {public ListNode EntryNodeOfLoop(ListNode pHead) {ListNode fast = pHead;ListNode slow = pHead;while(fast.next!=null && fast.next.next!=null){fast = fast.next.next;slow = slow.next;if(fast==slow){ //判断有没有环break;}}if(fast.next==null || fast.next.next==null){ //无环返回nullreturn null;}slow = pHead;while (slow != fast) { //找到环入口fast = fast.next;slow = slow.next;}return fast;}
}
JZ22 链表中倒数最后k个结点
![[图片]](https://img-blog.csdnimg.cn/0897850fb40947098eac544ed39f6fd3.png)
![[图片]](https://img-blog.csdnimg.cn/d68463dff2c647bb815b1fd9f25d65dc.png)
思路:快慢指针,先让一个指针走k步,后面同步一个个走,快指针走到末尾的时慢指针刚好指向末尾第k个节点。
import java.util.*;/** public class ListNode {* int val;* ListNode next = null;* public ListNode(int val) {* this.val = val;* }* }*/public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** * @param pHead ListNode类 * @param k int整型 * @return ListNode类*/public ListNode FindKthToTail (ListNode pHead, int k) {// write code hereif(pHead == null){return null;}ListNode slow = pHead;ListNode fast = pHead;while(k-->0){if(fast == null)return null;fast = fast.next; //先走k步}while(fast != null){fast = fast.next;slow = slow.next;}return slow;}
}
JZ35 复杂链表的复制
![[图片]](https://img-blog.csdnimg.cn/977e897d96e14499b656e4de0c8ad6cd.png)
![[图片]](https://img-blog.csdnimg.cn/2cfe05be42d0404da56d967d51a706ac.png)
思路:参考这篇博客 https://blog.csdn.net/qq_43676757/article/details/106253305
使用常规方法一,将步骤分成三个:
-
复制节点
![[图片]](https://img-blog.csdnimg.cn/bbf8edbebfed489992393293b269b695.png)
-
复制random节点给已拷贝节点
![[图片]](https://img-blog.csdnimg.cn/46a8c0adda3c4c87a723d629158650ea.png)
-
拆分链表
![[图片]](https://img-blog.csdnimg.cn/9125cc2dc08c47a99690126d86f2de84.png)
/*
public class RandomListNode {int label;RandomListNode next = null;RandomListNode random = null;RandomListNode(int label) {this.label = label;}
}
*/
public class Solution {public RandomListNode Clone(RandomListNode pHead) {if(pHead==null)return null;RandomListNode cur = pHead;//遍历原始链表,复制while(cur!=null){//拷贝节点RandomListNode temp = new RandomListNode(cur.label);//添加新节点到原始链表当前节点后面temp.next=cur.next;cur.next=temp;cur=temp.next;}//连接新链表的random节点cur = pHead;//回到头节点RandomListNode temp = pHead.next;while(cur!=null){if(cur.random==null){temp.random=null;}else{temp.random = cur.random.next; //新链表的random为cur的random下一个}cur = cur.next.next;if(temp.next!=null){temp=temp.next.next;}}//拆分链表cur = pHead;RandomListNode res = pHead.next;temp = res;while(cur!=null){cur.next=cur.next.next;cur=cur.next;if(temp.next!=null){temp.next = temp.next.next;}temp = temp.next;}return res;}
}
JZ76 删除链表中重复的结点
![[图片]](https://img-blog.csdnimg.cn/3edbd15d207b4278a3acbe172a671c80.png)
![[图片]](https://img-blog.csdnimg.cn/616e6cbd307e422198c496ee75a10193.png)
思路:需要前一个节点、当前节点和下一节点的信息。在表头添加一个节点作为pre,当前节点和下一节点相同的时候,当前指针往下移动;当数值不同的时才退出循环,将pre.next指向下一个节点。
/*public class ListNode {int val;ListNode next = null;ListNode(int val) {this.val = val;}
}
*/
public class Solution {public ListNode deleteDuplication(ListNode pHead) {// 链表为空或者只有一个节点if(pHead == null || pHead.next==null){return pHead;}ListNode res = new ListNode(-1); //表头加一个节点res.next = pHead;ListNode pre = res;ListNode cur = pHead;while(cur!=null && cur.next!=null){if(cur.val == cur.next.val){ //相邻的节点值相同int tmp = cur.val;while(cur.next!=null && cur.next.val==tmp){cur = cur.next; //跳过相同的节点 }//退出循环时,cur指向最后一个重复值cur = cur.next;pre.next = cur;}else{pre=cur;cur=cur.next;}}return res.next;}
}
JZ18 删除链表的节点
![[图片]](https://img-blog.csdnimg.cn/8e4cf335f88d4a7e91c011ef783d1ade.png)
思路:直观的想法就是记录下前一个节点,当搜索到匹配的数值,将前一个节点的next直接指向当前节点的下一个节点,达到删除当前节点的目的。特殊情况是表头节点满足条件!
import java.util.*;/** public class ListNode {* int val;* ListNode next = null;* public ListNode(int val) {* this.val = val;* }* }*/public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** * @param head ListNode类 * @param val int整型 * @return ListNode类*/public ListNode deleteNode (ListNode head, int val) {// write code here//1. 空则返回nullif(head == null){ return null;}ListNode pre = head; //pre记录当前节点前一个节点ListNode cur = head.next;//2.第一个元素就满足val,删除第一个元素if(pre!=null&&pre.val==val){pre=pre.next;return pre;}//3.第二个元素开始匹配while(cur!=null){if(cur.val==val){pre.next = cur.next;cur.next = null;break;}cur = cur.next;pre = pre.next;}return head;}
}
更简洁的代码(来源牛客网题解):在单链表前再加一个节点( ListNode res = new ListNode(0); res.next = head; ),返回的时候记得去掉。
import java.util.*;
public class Solution {public ListNode deleteNode (ListNode head, int val) {//加入一个头节点ListNode res = new ListNode(0);res.next = head;//前序节点ListNode pre = res;//当前节点ListNode cur = head;//遍历链表while(cur != null){//找到目标节点if(cur.val == val){//断开连接pre.next = cur.next;break;}pre = cur;cur = cur.next;}//返回去掉头节点return res.next;}
}
2. 树
相关文章:
【Java算法题】剑指offer_01数据结构
前言 刷题链接: https://www.nowcoder.com/exam/oj/ta?page2&tpId13&type265 1. 链表 JZ24 反转链表 思路:基本操作,如下所示。 /* public class ListNode {int val;ListNode next null;ListNode(int val) {this.val val;} }…...
最简单配置jenkins容器使用宿主机的docker方法
构建镜像和发布镜像到harbor都需要使用到docker命令。而在Jenkins容器内部安装Docker官方推荐直接采用宿主机带的Docker即可 设置Jenkins容器使用宿主机Docker 设置宿主机docker.sock权限 chown root:root /var/run/docker.sock chmod orw /var/run/docker.sock 添加数据卷 v…...
Android aidl及binder基础知识巩固
作者:义华 1、什么是binder binder是android framework提供的,用于跨进程方法调用的机制,具有安全高效等特点。 我们知道,在 Android 系统中,每个应用程序都运行在一个独立的进程中,各个进程之间需要进行…...
[日记]LeetCode算法·二十五——二叉树⑤ AVL树(插入+删除)附代码实现
本章的代码实现基于上一篇BST与优先队列的基类进行平衡二叉树,即AVL树。 文章目录 AVL的概念AVL查询效率AVL的插入1.插入节点2.更新平衡因子BF3.旋转调整树的结构3.1 LL 右旋3.2 RR 左旋3.3 LR 左右双旋3.4 RL 右左双旋 4 插入总结 AVL的删除1.寻找删除节点2.更新平…...
flink-1.13.6 例子
-------------------------------------------------------------- flink版本: flink-1.13.6 [rootmaster bin]# pip3 list | grep flink WARNING: Ignoring invalid distribution -andas (/usr/local/python38/lib/python3.8/site-packages) apache-flink 1.13.0 a…...
Go语音基于zap的日志封装
zap日志封装 Zap是一个高性能、结构化日志库,专为Go语言设计。它由Uber开源,并且在Go社区中非常受欢迎。它的设计目标是提供一个简单易用、高效稳定、灵活可扩展的日志系统。 以下是Zap的一些主要特点: 1.高性能:Zap的性能非常出…...
可持续能源技术具有改变世界的潜力,并且已经在多个方面展现出积极的影响。
可持续能源技术的发展在当今全球面临的气候变化和能源安全挑战中扮演着至关重要的角色。我认为可持续能源技术具有改变世界的潜力,并且已经在多个方面展现出积极的影响。以下是我对此的观点: 1,可持续能源技术有助于减少对化石燃料的依赖 化…...
Java常用工具之StringUtils类
目录 一、字符串判空二、分隔字符串三、判断是否为纯数字四、将集合拼接成字符串五、其他方法 字符串(String)在我们的日常工作中,用得非常非常非常多。 在我们的代码中经常需要对字符串判空,截取字符串、转换大小写、分隔字符串、…...
MyBatis-plus的批量插入方式对比分析
MyBatis-plus的批量插入方式对比分析 【摘要】Mybatis批量插入一直是开发者重点关注的问题,本文列举了Mybatis的五种插入方式进行对比分析,验证了五种批量插入的方式的优先级。 1 准备工作 1.1 新建spring项目 略。 1.2 导入pom.xml依赖 <depende…...
【系分论文】论软件开发模型及应用
目录 论题论题介绍论文要点理论素材准备范文摘要正文 论文补充知识 论题 论软件开发模型及应用 论题介绍 软件开发模型( Software Development Model)是指软件开发全部过程、活动和任务的结构框架。软件开发过程包括需求、设计、编码和测试等阶段&…...
渗透测试--5.3.使用john破解密码
前言 由于Linux是Internet最流行的服务器操作系统,因此它的安全性备受关注。这种安全主要靠口令实现。 Linux使用一个单向函数crypt()来加密用户口令。单向函数crypt()从数学原理上保证了从加密的密文得到加密前的明…...
Go中的变量类型
Go中的变量类型 1.为什么要使用变量 变量其实指定的是一段内存地址,根据这个内存地址可以找到我们需要找到的东西。 2.变量类型 变量的功能就是用来存储数据的,根据不同的数据类型可以存储不同的数据。常见的变量的类型 整型、浮点型、布尔型等。变…...
基于STM32的NRF24L01 2.4G通讯模块的驱动实验(HAL库)
前言:本文为手把手教学NRF24L01 2.4G通讯模块的驱动实验,本教程的 MCU 采用STM32F103ZET6与STM32F103C8T6,彼此进行互相通讯。通过 CubeMX 软件配置 SPI 协议驱动NRF24L01 2.4G通讯模块(HAL库)。NRF24L01 2.4G是嵌入式…...
DJ5-3 多路访问链路和协议
目录 一、网络链路 二、广播信道要解决问题 三、多路访问协议 1、基本介绍 2、多路访问协议的类型(3) 四、信道划分协议 1、时分多路访问 TDMA 2、频分多路访问 FDMA 3、码分多路访问 CDMA(略) 五、随机访问协议 1、纯…...
技术领导力?
作品集(Portfolio)会比简历(Resume)更有参考意义。 怎么才算有技术领导力? 1) 能够发现问题,并能够提供解决问题的思路和方案,并能比较方案的优缺点。 2) 能用更简洁有效的方式解决问题。 3…...
计算机的基本工作原理
参考资料: L-1.6: Common Bus system| How basic computer works - YouTube 准备好内存单元、不同类型的寄存器,内存和寄存器、寄存器和寄存器之间都是通过总线连接(假设是直接把数据总线、控制总线、地址总线变成一条总线)。 使用多路复用器实现的总线&…...
【论文简述】Cross-Attentional Flow Transformer for Robust Optical Flow(CVPR 2022)
一、论文简述 1. 第一作者:Xiuchao Sui、Shaohua Li 2. 发表年份:2021 3. 发表期刊:arxiv 4. 关键词:光流、Transformer、自注意力、交叉注意力、相关体 5. 探索动机:由于卷积的局部性和刚性权重,有限…...
【JAVA】Java中方法的使用,理解方法重载和递归
目录 1.方法的概念及使用 1.1什么是方法 1.2方法的定义 1.3方法调用的执行过程 1.4实参和形参 2.方法重载 2.1为什么需要使用方法重载 2.2什么是方法重载 3.递归 3.1什么是递归 3.2递归执行的过程 3.3递归的使用 1.方法的概念及使用 1.1什么是方法 方法就是一个代…...
高级网络计算模式复习
P2P 对等网络(Peer-to-Peer Networks)是分布式系统和计算机网络相结合的产物,在应用领域和学术界获得了广泛的重视和成功,被称为“改变Internet的一代网络技术”。 peer指网络结点,在行为上是自由的——任意加入、退…...
【笔试强训选择题】Day15.习题(错题)解析
作者简介:大家好,我是未央; 博客首页:未央.303 系列专栏:笔试强训选择题 每日一句:人的一生,可以有所作为的时机只有一次,那就是现在!! 文章目录 前言 一、…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
