【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 系列专栏:笔试强训选择题 每日一句:人的一生,可以有所作为的时机只有一次,那就是现在!! 文章目录 前言 一、…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
