算法(二)——数组章节和链表章节
数组章节
(1)二分查找
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
class Solution {public int search(int[] nums, int target) {//二分查找法int right=nums.length-1;int left=0;while(left<=right){int mid=(right+left)/2;if(target<nums[mid]){right=mid-1;}else if(target>nums[mid]){left=mid+1;}else{return mid;}}return -1;}
}
(2)双指针——移除元素
- 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
- 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
- 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
class Solution {public int removeElement(int[] nums, int val) {//双指针(quick-遍历数组 slow-将不等于val的元素依次插入新数组)int slow=0;for(int quick=0;quick<nums.length;quick++){if(nums[quick]!=val){nums[slow]=nums[quick];slow++;}}return slow; //slow指针指向空位,等待插入,所以slow值等于新数组长度}
}
(3)有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
class Solution {public int[] sortedSquares(int[] nums) {// 结果数组int n = nums.length;int[] result = new int[n];// 双指针int left = 0;int right = n - 1;while (left <= right) {if (Math.pow(nums[left], 2) >= Math.pow(nums[right], 2)) {result[n - 1] = (int) Math.pow(nums[left], 2);left++;} else {result[n - 1] = (int) Math.pow(nums[right], 2);right--;}n--;}return result;}
}
(4)长度最小的子数组
- 给定一个含有 n 个正整数的数组和一个正整数 target 。
- 找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
class Solution {public int minSubArrayLen(int target, int[] nums) {int res = 2147483647;//整数最大值int len;int sum=0;int i=0;//i 为窗口开始位置,j 为窗口终止位置for(int j=i;j<nums.length;j++){sum+=nums[j];while(sum>=target){len=j-i+1;res=Math.min(len,res);sum-=nums[i++];//不断移动i,直到区间内的和< target}//跳出while循环后,遍历继续j,j指针重新与i指针合并}return res==2147483647? 0:res;//数组总和都达不到target,res没有改变}
}
(5)螺旋矩阵
给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
class Solution {public List<Integer> spiralOrder(int[][] matrix) {//这个二维数组行列不确定List<Integer> result = new ArrayList<>();//matrix.length 行数//matrix[0].length 列数if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {return result;}int rows = matrix.length; //行int cols = matrix[0].length; //列//定义四个变量top、bottom、left、right,分别表示当前遍历的上边界、下边界、左边界和右边界。//初始时,上边界为0,下边界为行数减1,左边界为0,右边界为列数减1。int top = 0, bottom = rows - 1, left = 0, right = cols - 1;while (top <= bottom && left <= right) {// 从左到右if(right!=0){ //判断只有一列的情况for (int i = left; i <= right; i++) {result.add(matrix[top][i]);}top++;}// 从上到下if(bottom!=0){//判断只有一行的情况for (int i = top; i <= bottom; i++) {result.add(matrix[i][right]);}right--;}// 从右到左if (top <= bottom) {for (int i = right; i >= left; i--) {result.add(matrix[bottom][i]);}bottom--;}// 从下到上if (left <= right) {for (int i = bottom; i >= top; i--) {result.add(matrix[i][left]);}left++;}}return result;}
}
链表章节
(6)移除链表中的元素
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {//该方法没有头结点public ListNode removeElements(ListNode head, int val) {// 处理头节点为需要删除的节点的情况while (head != null && head.val == val) {//这个while需要注意head = head.next;}// 处理链表为空的情况(你前面持续删除首结点,当然得判断链表是不是被你删空嘞)if (head == null) {return head;}// 遍历链表,删除节点ListNode cur = head;while (cur.next != null) {if (cur.next.val == val) {cur.next = cur.next.next;} else {cur = cur.next;}}return head;
}
}
(7)设计链表
定义一个双链表,并实现它的基本操作
//双链表class ListNode{int val;ListNode next;ListNode prev;ListNode(){}ListNode(int val){this.val=val;}}
class MyLinkedList {//链表长度int size;//虚拟头结点ListNode head;public MyLinkedList() {size = 0;head = new ListNode(0);head.next = null;head.prev = null;}//根据索引查询并返回元素public int get(int index) {if (index < 0 || index >= size) {return -1;}ListNode curr = head;for (int i = 0; i <= index; i++) {curr = curr.next;}return curr.val;}//头插法public void addAtHead(int val) {ListNode newNode = new ListNode(val);newNode.next = head.next;newNode.prev = head;if (head.next != null) {head.next.prev = newNode;}head.next = newNode;size++;}//尾插法public void addAtTail(int val) {ListNode newNode = new ListNode(val);ListNode curr = head;while (curr.next != null) {curr = curr.next;}curr.next = newNode;newNode.prev = curr;size++;}//按索引添加新结点public void addAtIndex(int index, int val) {if (index < 0 || index > size) {return;}if (index == 0) {addAtHead(val);return;}if (index == size) {addAtTail(val);return;}ListNode newNode = new ListNode(val);ListNode curr = head;for (int i = 0; i < index; i++) {curr = curr.next;}newNode.next = curr.next;newNode.prev = curr;curr.next.prev = newNode;curr.next = newNode;size++;}//按索引删除结点public void deleteAtIndex(int index) {if (index < 0 || index >= size) {return;}ListNode curr = head;for (int i = 0; i < index; i++) {curr = curr.next;}curr.next = curr.next.next;if (curr.next != null) {curr.next.prev = curr;}size--;}
}/*** Your MyLinkedList object will be instantiated and called as such:* MyLinkedList obj = new MyLinkedList();* int param_1 = obj.get(index);* obj.addAtHead(val);* obj.addAtTail(val);* obj.addAtIndex(index,val);* obj.deleteAtIndex(index);*/
(8)翻转链表
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode reverseList(ListNode head) {//双链表ListNode cur=head;ListNode pre=null;ListNode temp=new ListNode();while(cur!=null){temp=cur.next;cur.next=pre;//这两步不能颠倒pre=cur;cur=temp;}return pre;}
}
(9)两两交换链表中的结点
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode swapPairs(ListNode head) {ListNode demo=new ListNode();//虚拟头结点demo.next=head;//让虚拟头结点指向head首结点ListNode cur=demo;//遍历指针ListNode first;//保存需要交换的第一个结点ListNode second;//保存需要交换的第二个结点ListNode temp;//临时变量存储结点//开始遍历while(cur.next!=null && cur.next.next!=null){//分别考虑链表长度为偶数和奇数情况first=cur.next;second=cur.next.next;//开始交换位置temp=cur.next.next.next;//保存第二组结点的第一个结点//开始交换cur.next=second;second.next=first;first.next=temp;//cur需要变到下一组的前面结点cur=first;//注意此时链表的顺序以及改变}return demo.next;}
}
(10)删除链表的倒数第n个结点
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode removeNthFromEnd(ListNode head, int n) {//虚拟头结点ListNode demo=new ListNode(-1);demo.next=head;//双指针法ListNode slow=demo;ListNode fast=demo;//fast首先走n + 1步 //因为只有这样同时移动的时候slow才能指向删除节点的上一个节点(方便做删除操作for (int i = 0; i < n ; i++){fast=fast.next;}//双指针开始同步右移while(fast.next!=null){fast=fast.next;slow=slow.next;}//此时slow指针指向倒数第N+1个结点//开始删除slow.next=slow.next.next;//这里返回的是demo.next而不是head;return demo.next;}
}
(11)链表相交
"双指针法"具体步骤如下:
- 创建两个指针p1和p2,分别指向两个链表的头节点。
- 同时移动两个指针p1和p2,每次移动一个节点。
- 当其中一个指针到达链表末尾时(即指向null),将它指向另一个链表的头结点。
- 继续移动两个指针,直到它们相遇或者都指向null。
- 如果两个指针相遇,则说明两个链表有交点,返回该节点。
- 如果两个指针都指向null,则说明两个链表没有交点,返回null。
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) {* val = x;* next = null;* }* }*/
public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {if(headA==null || headB==null) return null;//双指针法ListNode p1=headA;ListNode p2=headB;//开始遍历while(p1!=p2){if(p1==null){p1=headB;}else{p1=p1.next;}if(p2==null){p2=headA;}else{p2=p2.next;}}return p1;}
}
(12)环型链表
- 给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
- 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。
- 为了表示给定链表中的环,评测系统内部使用整数 pos来表示链表尾连接到链表中的位置(索引从 0开始)。
- 如果 pos 是 -1,则在该链表中没有环。
- 注意:pos不作为参数进行传递,仅仅是为了标识链表的实际情况。
- 不允许修改 链表。
/*** Definition for singly-linked list.* class ListNode {* int val;* ListNode next;* ListNode(int x) {* val = x;* next = null;* }* }*/
public class Solution {public ListNode detectCycle(ListNode head) {//数学题(追击问题)//有环必相遇//第一步:判断是否有环ListNode slow=head;ListNode fast=head;while(fast!=null && fast.next!=null){slow=slow.next;//一次移动一个结点fast=fast.next.next;//一次移动两个结点if(slow==fast){//有环//第一步:找环的第一个结点//根据公式,存在n=1,即快指针在第二圈途中与慢指针相遇,浪漫吗? 累成狗了,浪漫个屁。ListNode slowRecord=slow;//记录彼此的第一次邂逅,慢指针依旧原地开始走ListNode fastEx=head;//快指针回head首结点重新开始追while(slowRecord!=fastEx){//这回两人都得一步一步走,直到相遇,相遇点即为环入口slowRecord=slowRecord.next;fastEx=fastEx.next;}return slowRecord;}}//无环无缘喽return null;}
}
相关文章:

算法(二)——数组章节和链表章节
数组章节 (1)二分查找 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。 class Solution {public i…...

Android:ListView在Fragment中的使用
一、前言: 因为工作一直在用mvvm框架,因此这篇文章是基于mvvm框架写的。在Fragment复制之前一定要谨记项目可以跑起来。确保能跑起来之后直接复制就行。 二、代码展示: 页面布局 ?xml version"1.0" encoding"utf-8"…...

BIGEMAP在土地规划中的应用
工具 Bigemap gis office地图软件 BIGEMAP GIS Office-全能版 Bigemap APP_卫星地图APP_高清卫星地图APP 1.使用软件一般都用于套坐标,比如我们常见的(kml shp CAD等土建规划图纸)以及一些项目厂区红线,方便于项目选址和居民建…...

软件测试常见术语和名词解释
1. Unit testing (单元测试):指一段代码的基本测试,其实际大小是未定的,通常是一个函数或子程序,一般由开发者执行。 2. Integration testing (集成测试):被测试系统的所有组件都集成在一起,找出被测试系统…...

prometheus+process_exporter进程监控
一、需要监控进程的服务器上配置 1、进入到临时工作目录,传入process_exporter包 [root Nginx1 ~]# cd work/ [root Nginx1 work]# rz 2、解压,并移动至/usr/local/目录下 [root Nginx1 work]# tar xzf process-exporter-0.7.5.linux-amd64.tar.gz [root…...

四川玖璨电子商务有限公司专注抖音电商运营
四川玖璨电商是一个靠谱的抖音培训公司,在电商行业内有着广泛的知名度和良好的口碑。该公司通过多年的发展,形成了独特的运营理念和有效的运营策略,为商家提供了一站式的抖音电商运营服务。 首先,四川玖璨电子商务有限公司注重与…...
python LeetCode 刷题记录 83
题目 给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。 代码 class Solution:def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]:if head:# 判断非空链表current he…...
Grom 如何解决 SQL 注入问题
什么是 SQL 注入 SQL 注入是一种常见的数据库攻击手段, SQL 注入漏洞也是网络世界中最普遍的漏洞之一。 SQL 注入就是恶意用户通过在表单中填写包含 SQL 关键字的数据来使数据库执行非常规代码的过程。 这个问题的来源就是, SQL 数据库的操作是通过 SQ…...

腾讯mini项目-【指标监控服务重构】2023-07-19
今日已办 OpenTelemetry Logs 通过日志记录 API 支持日志收集 集成现有的日志记录库和日志收集工具 Overview 日志记录 API - Logging API,允许您检测应用程序并生成结构化日志旨在与其他 telemerty data(例如metric和trace)配合使用&am…...

抖音矩阵系统源代码开发部署--SaaS开源技术开发文档
一、概述 抖音SEO矩阵系统源代码是一套针对抖音平台的搜索引擎优化工具,它可以帮助用户提高抖音视频在搜索结果中的排名,增加曝光率和流量。本开发文档旨在提供系统的功能框架、技术要求和开发示例,以便开发者进行二次开发和优化。 二、功能…...
CLIP模型资料学习
clip资料 links https://blog.csdn.net/wzk4869/article/details/129680734?ops_request_misc&request_id&biz_id102&utm_termCLIP&utm_mediumdistribute.pc_search_result.none-task-blog-2allsobaiduweb~default-4-129680734.142v94insert_down1&spm10…...

【c语言】贪吃蛇
当我们不想学习新知识的时候,并且特别无聊,就会突然先看看别人怎么写游戏的,今天给大家分享的是贪吃蛇,所需要的知识有结构体,枚举,以及easy-x图形库的一些基本函数就完全够用了,本来我想插入游…...

【Node.js】定时任务cron:
文章目录 一、文档:【Nodejs 插件】 二、安装与使用【1】安装【2】使用 三、cron表达式:{秒数} {分钟} {小时} {日期} {月份} {星期} {年份(可为空)}四、案例: 一、文档: 【说明文档】https://www.npmjs.com/package/cron 【Cron表…...
vue3 引入element-plus
1.首先安装element-plus npm install element-plus 2.main.js配置 ... import ElementPlus from element-plus import element-plus/theme-chalk/index.css; //导入图标 import * as ELementPlusIconsVue from "element-plus/icons-vue" ... app.use(ElementPlus) /…...

数据通信——传输层TCP(超时时间选择)
引言 TCP每一次发送报文段,就会对这个报文段设置一次计时器。如果时间到了却没有收到确认报文,那么就要重传该报文。 这个之前在TCP传输的机制中提到过,这个章节就来研究一下超时时间问题。 关于加权的概念 有必要提及一下加权的概念&#x…...
【数据库索引优化】
文章目录 数据库索引优化1. 选择合适的字段创建索引2. 限值每张表上的索引数量3. 被频繁更新的字段应该慎重建立索引4. 尽可能考虑简历联合索引而不是单列索引5. 避免冗余索引6. 字符串类型的字段使用前缀索引代替普通索引7. 避免索引失效8. 删除长期未使用的索引 数据库索引优…...

WebGL 选中物体
目录 前言 如何实现选中物体 示例程序(PickObject.js) 代码详解 gl.readPixels()函数规范 示例效果 前言 有些三维应用程序需要允许用户能够交互地操纵三维物体,要这样做首先就得允许用户选中某个物体。对物体…...

科目二倒车入库
调整座位和后视镜 离合踩到底大腿小腿成130-140 上半身90-100 座椅高度能看到前方全部情况 后视镜调节到能看到后门把手,且后门把手刚好在后视镜上方边缘、离车1/3处。 保持直线: 前进: 车仪表盘中央的原点和地面上的黄线擦边ÿ…...

PostgreSQL如何支持PL/Python过程语言
瀚高数据库 目录 环境 文档用途 详细信息 环境 系统平台:Linux x86-64 Red Hat Enterprise Linux 7 版本:10.4 文档用途 本文档主要介绍PostgreSQL如何支持PL/Python过程语言,如何创建plpython扩展。 详细信息 一、PostgreSQL支持python语言…...

【C++】STL之适配器---用deque实现栈和队列
目录 前言 一、deque 1、deque 的原理介绍 2、deque 的底层结构 3、deque 的迭代器 4、deque 的优缺点 4.1、优点 4.2、缺点 二、stack 的介绍和使用 1、stack 的介绍 2、stack 的使用 3、stack 的模拟实现 三、queue 的介绍和使用 1、queue 的介绍 2、queue 的使用 3、qu…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...

【UE5 C++】通过文件对话框获取选择文件的路径
目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 ,这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器,右键点击 .uproject 文件,选择 "Generate Visual Studio project files",重…...

Unity VR/MR开发-VR开发与传统3D开发的差异
视频讲解链接:【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...
基于Java项目的Karate API测试
Karate 实现了可以只编写Feature 文件进行测试,但是对于熟悉Java语言的开发或是测试人员,可以通过编程方式集成 Karate 丰富的自动化和数据断言功能。 本篇快速介绍在Java Maven项目中编写和运行测试的示例。 创建Maven项目 最简单的创建项目的方式就是创建一个目录,里面…...

SFTrack:面向警务无人机的自适应多目标跟踪算法——突破小尺度高速运动目标的追踪瓶颈
【导读】 本文针对无人机(UAV)视频中目标尺寸小、运动快导致的多目标跟踪难题,提出一种更简单高效的方法。核心创新在于从低置信度检测启动跟踪(贴合无人机场景特性),并改进传统外观匹配算法以关联此类检测…...
python数据结构和算法(1)
数据结构和算法简介 数据结构:存储和组织数据的方式,决定了数据的存储方式和访问方式。 算法:解决问题的思维、步骤和方法。 程序 数据结构 算法 算法 算法的独立性 算法是独立存在的一种解决问题的方法和思想,对于算法而言&a…...