JAVA刷题之数组的总结和思路分享

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱
ʕ̯•͡˔•̯᷅ʔ大家好,我是xiaoxie.希望你看完之后,有不足之处请多多谅解,让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客
本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如需转载还请通知˶⍤⃝˶
个人主页:xiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客
系列专栏:xiaoxie的刷题系列专栏——CSDN博客●'ᴗ'σσணღ*
我的目标:"团团等我💪( ◡̀_◡́ ҂)" 

( ⸝⸝⸝›ᴥ‹⸝⸝⸝ )欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​+关注(互三必回)! 

beb57f2cc888447ab7e8bbdd4bb1bc08.png

数组篇 

1. 在排序数组中查找元素的第一个和最后一个位置

力扣链接

d1c87083f7bd4365a26e4484ba53a714.png

 我相信大家一看到这题是有序的数组,有点基础的同学们都会想到二分查找法,这一题有思路很容易,但提交时却老是无法通过,这就是因为没有考虑好边界问题了,现在博主为大家介绍两种二分查找法

1.普通二分查找法

做好这一题的关键就在于找到边界

题就是查找 target 在 nums 中的区间,即查找 target 在 nums 中的左右边界。

仔细想的话,要找 target 在 nums 数组中的左右边界,无非存在 3 种情况:

target 在 nums[0] ~ nums[n-1] 中,nums 中存在 target。例如 nums = [5,7,7,8,8,10],target = 8,返回 [3,4]。
target 在 nums[0] ~ nums[n-1] 中,nums 中不存在 target。例如 nums = [5,7,7,8,8,10],target = 6,返回 [-1,-1]。
target < nums[0] 或者 target > nums[n-1]。例如 nums = [5,7,7,8,8,10], target = 4,返回 [-1,-1]。

用两个二分查找,一个二分查找查找左边界,另一个查找右边界,分情况讨论上述的 3 种情况。


class Solution {public int[] searchRange(int[] nums, int target) {int start = lowerBound(nums, target);if (start == nums.length || nums[start] != target)return new int[]{-1, -1};// 如果 start 存在,那么 end 必定存在int end = lowerBound(nums, target + 1) - 1;return new int[]{start, end};}private int lowerBound(int[] nums, int target) {int left = 0, right = nums.length - 1; // 闭区间 [left, right]while (left <= right) { // 区间不为空int mid = left + (right - left) / 2;if (nums[mid] < target)left = mid + 1; // 范围缩小到 [mid+1, right]elseright = mid - 1; // 范围缩小到 [left, mid-1]}return left; // right+1}

2.红蓝二分查找法

相信大家一直对二分查找法的边界问题一直有困扰,一般来说二分查找就这些东西,在边界和细节上搞人,只要每次做题小心点,就没啥问题。现在博主就为大家介绍另外一种二分查找方法,它不需要考虑那么多问题,只要在最后返回值时多多注意就好了

class Solution {public int searchRangeLeft(int[] nums, int target) {int left = -1;int right = nums.length;while (left + 1 != right) {int mid = (left + right) / 2;if (nums[mid] <= target) {left = mid;} else {right = mid;}}return left;}public int searchRangeRight(int[] nums, int target) {int left = -1;int right = nums.length;while (left + 1 != right) {int mid = (left + right) / 2;if (nums[mid] < target) {left = mid;} else {right = mid;}}return right;}public int[] searchRange(int[] nums, int target) {int leftIndex = searchRangeLeft(nums, target);int rightIndex = searchRangeRight(nums, target);if (leftIndex >= rightIndex && leftIndex < nums.length && nums[leftIndex] == target && nums[rightIndex] == target) {return new int[] {rightIndex, leftIndex};}return new int[] {-1, -1};}
}

开始时,L指针和 R指针取在搜索区间界外,L=首个元素下标−1,R=末尾元素下标+1,此时所有元素均未着色;
循环条件始终为 L+1 < R,当 L=R 时跳出循环,此时蓝红区域划分完成,所有元素均已着色;
M指针取值始终为 M =(L+R)/2
L指针和 R指针变化的时候直接变为 M指针,即对 M 指针所指向元素进行染色,无需 +1 或者−1;
本模板唯一变化的地方是判断目标元素最终落在左边蓝色区域还是右边红色区域。以不变应万变,根据情况的不同,变换判断条件,大大的降低了出错的可能。

bd82c988822748eb88c81136a103413c.png

98fe462e031541f68718b4eb0b29a65f.png

 这样就找到左下标和右下标啦,再因为该题是找不到就返回-1,所以还要再判断,同时红蓝二分查找法并不只是适用于这题哦,它在大部分的题目都适用,目前博主还没有遇到不适用的情况,所以大家可以放心用,在变换判断条件时和普通二分查找法,大大的降低了出错的可能。

2. 删除有序数组中的重复项---快慢指针

d069c12c176c4d1c9b7d7e3a4d3fb6a3.png

这是力扣上的一道简单题,有的同学可能说了,多余的元素,删掉不就得了。

要知道数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖,所以从中我们第一时间想到也是最简单的就是暴力解法

1.暴力解法

这个题目暴力的解法就是两层for循环,一个for循环遍历数组元素 ,第二个for循环更新数组。

public int removeDuplicates(int[] nums) {if (nums.length == 0) {return 0;}int k = 1; // 记录唯一元素的个数for (int i = 1; i < nums.length; i++) {boolean isDuplicate = false;// 检查当前元素是否已经存在于前面的唯一元素中for (int j = 0; j < k; j++) {if (nums[i] == nums[j]) {isDuplicate = true;break;}}// 如果当前元素是新的唯一元素,则加入到唯一元素列表中if (!isDuplicate) {nums[k] = nums[i];k++;}}return k;
}

 很明显暴力解法的时间复杂度是O(n^2),这道题目暴力解法在leetcode上是可以过的。但这面试中你写这个解法,显然是不能让面试官满意的。博主这有一个使用双指针,快慢指针的解法

2.快慢指针

双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。

定义快慢指针

  • 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
  • 慢指针:指向更新 新数组下标的位置

很多同学这道题目做的很懵,就是不理解 快慢指针究竟都是什么含义,所以一定要明确含义,后面的思路就更容易理解了。要解这题的思路如下

首先我们写记录下数组第一个元素的数值:

 int val = nums[0];

然后我们在定义一个快指针和慢指针,指向数组第二个元素:然后快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组;慢指针:指向更新 新数组下标的位置,如下图:

025a42c81a934713a2391590433fd070.png

public int removeDuplicates(int[] nums) {int val = nums[0]; // 记录当前唯一元素的值int slow = 1; // 慢指针,指向下一个唯一元素应该存放的位置for (int fast = 1; fast < nums.length; fast++) {if (nums[fast] != val) { // 如果当前元素与前一个唯一元素不相同nums[slow] = nums[fast]; // 将当前元素存放到慢指针指向的位置val = nums[slow]; // 更新当前唯一元素的值slow++; // 慢指针向后移动}}return slow; // 返回唯一元素的个数
}

双指针法(快慢指针法)在数组和链表的操作中是非常常见的,很多考察数组、链表、字符串等操作的面试题,都使用双指针法,写成这样你的代码才可以说达到了面试的高度了,所以我们遇到这一类的题型可以多往快慢指针法那边靠靠,我相信你多练习,多学习,一定可以做到更好。

3.长度最小的子数组

6f80fdd3692b4c0c87c4b07783195d1b.png

 这是力扣上的一道中等难度的数组题,还是一样看到这一题,第一个想到的方法就是用两个for 循环的暴力解法

1.暴力解法

public class Solution {public int minSubArrayLen(int s, int[] nums) {int result = Integer.MAX_VALUE; // 最终的结果int sum = 0; // 子序列的数值之和int subLength = 0; // 子序列的长度for (int i = 0; i < nums.length; i++) { // 设置子序列起点为isum = 0;for (int j = i; j < nums.length; j++) { // 设置子序列终止位置为jsum += nums[j];if (sum >= s) { // 一旦发现子序列和超过了s,更新resultsubLength = j - i + 1; // 取子序列的长度result = result < subLength ? result : subLength;break; // 因为我们是找符合条件最短的子序列,所以一旦符合条件就break}}}// 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列return result == Integer.MAX_VALUE ? 0 : result;}
}

2.滑动窗口

该如何把两个for循环变成一个呢,我想大家想到的一定是双指针,对没错,使用双指针,现在博主来为大家介绍一种双指针方法,滑动窗口。所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。它一样是使用双指针,只不过这种解法更像是一个窗口的移动,所以就称为滑动窗口。

在本题中实现滑动窗口,主要确定如下三点:

  • 窗口内是什么?
  • 如何移动窗口的起始位置?
  • 如何移动窗口的结束位置?

窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。

窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。

窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。

解题的关键在于 窗口的起始位置如何移动,如图所示:

760367123a294e95b5d6ff8488933fa3.png

代码如下:

class Solution {public int minSubArrayLen(int target, int[] nums) {int result = Integer.MAX_VALUE;int star = 0,end = 0;int sum = 0;for(;end < nums.length; end++) {sum += nums[end];while(sum >= target) {int subl = end - star+1;result = Math.min(subl,result);//动态更新数值sum -= nums[star++];} }return result == Integer.MAX_VALUE ? 0 : result;}
}

好了这就是数组篇的全部内容了,后续博主还会持续更新,链表篇等等内容,大家可以点个关注,不错过后续精彩内容。感谢您的阅读,祝您一天生活愉快 

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

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

相关文章

C语言第十六集(前)

1.关于那个整形存储入char的 是先取好补码,再截断 例: 2.%u是以十进制的形式打印无符号整数 3.注意(背):存储的char类型变量的补码为10000000的直接解析为-128 4.signed char 类型的变量取值范围是-128~127 5.unsigned char 类型的变量取值范围是0~255 6.有符号类型的变量…

2023.12.6 关于 Spring Boot 事务的基本概念

目录 事务基本概念 前置准备 Spring Boot 事务使用 编程式事务 声明式事务 Transactional 注解参数说明 Transational 对异常的处理 解决方案一 解决方案二 Transactional 的工作原理 面试题 Spring Boot 事务失效的场景有那些&#xff1f; 事务基本概念 事务指一…

如何解决5G基站高能耗问题?

安科瑞 须静燕 截至2023年10月&#xff0c;我国5G基站总数达321.5万个&#xff0c;占全国通信基站总数的28.1%。然而&#xff0c;随着5G基站数量的快速增长&#xff0c;基站的能耗问题也逐渐日益凸显&#xff0c;基站的用电给运营商带来了巨大的电费开支压力&#xff0c;降低5…

vue项目配置多个代理

在本地.env文件配置本地/测试/预发/正式 路径&#xff1a; 在vue.config.js 里面配置&#xff1a; module.exports defineConfig({transpileDependencies: false,lintOnSave: false,outputDir: process.env.VUE_APP_DIST,publicPath: /,css: {loaderOptions: {postcss: {// p…

Motion Plan之轨迹生成代码实现 (1)

Motion Plan之搜索算法笔记Motion Plan之基于采样的路径规划算法笔记Motion Plan之带动力学约束路径搜索 Motion Plan之轨迹生成笔记文章开始前先回顾下上次的带约束的轨迹生成&#xff0c;轨迹生成本质就是曲线拟合。曲线拟合常用的方法有&#xff1a;多项式、贝赛尔曲线、三…

CPU密集型和IO密集型与CPU内核之间的关系

CPU密集型和IO密集型与CPU内核之间的关系 一、CPU密集型 介绍 CPU密集型&#xff0c;也叫计算密集型&#xff0c;是指需要大量CPU计算资源&#xff0c;例如大量的数学运算、图像处理、加密解密等。这种类型的任务主要依赖于CPU的计算能力&#xff0c;会占用大量的CPU时间片&am…

vcomp140.dll文件丢失解决方法分享:三种亲测有效方案

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“vcomp140.dll丢失”。这个错误提示通常出现在运行某些程序或游戏时&#xff0c;给使用者带来了很大的困扰。那么&#xff0c;vcomp140.dll丢失怎样修复呢&#xff1f;本文将详细介绍解决这…

网工内推 | 国企网工、运维,厂商认证优先,13薪,带薪年假

01 中百集团 招聘岗位&#xff1a;运维工程师 职责描述&#xff1a; 1、对集团内使用云计算架构&#xff08;Kubernetes&#xff09;的系统进行规划、运维及管理相关工作。 2、对集团数据中心系统的大数据基础架构&#xff08;Cloudera Distribution Hadoop&#xff09;的规划…

打补丁,生成.diff文件

作者&#xff1a;爱塔居 文章目录 目录 前言 步骤 一、在根目录上&#xff0c;输入添加指令 二、输入修改内容指令 三、生成补丁 前言 自己的理解&#xff0c;仅供参考&#xff0c;欢迎指正。 补丁的话&#xff0c;在我看来就是方便评审&#xff0c;更方便看修改代码吧。 步骤…

Python-关系运算符详解

关系运算符&#xff1a;比较两个操作数的大小或者相等关系 < > ! 1、关系运算符的关系表达式返回值是布尔类型bool 成立就是真&#xff0c;即1&#xff1b;不成立就是假&#xff0c;即0 2、关系运算符还可以比较字符 字符根据字典序比较&#xff0c;先看首字母在…

智能优化算法应用:基于人工大猩猩部队算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于人工大猩猩部队算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于人工大猩猩部队算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.人工大猩猩部队算法4.实验参数设…

Unity Meta Quest 一体机开发(九):【手势追踪】通过录制抓取手势实现自定义抓取姿势

文章目录 &#x1f4d5;教程说明&#x1f4d5;录制前的准备&#x1f4d5;第一种录制方法&#xff08;Hand Grab Pose Tool 场景&#xff09;⭐在运行模式中确认录制⭐保存录制的手势&#xff0c;将物体做成 Prefab⭐在编辑阶段调整抓取手势&#x1f50d;Fingers Freedom&#x…

德国进口高速主轴电机在机器人上的应用及选型方案

随着机器人技术的日新月异&#xff0c;高速主轴电机在机器人领域的应用也日趋广泛。德国进口的SycoTec高速主轴电机&#xff0c;以其高转速、高精度、高刚度的特点&#xff0c;在机器人的切割、铣削、钻孔、去毛刺等加工应用中发挥着关键作用。 一、高速主轴电机的特点 SycoT…

微信机器人接口开发

简要描述&#xff1a; 设置http回调地址 请求URL&#xff1a; http://域名地址/setHttpCallbackUrl POST 请求头Headers:&#xff08;别忘了传&#xff09; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必…

了解Linux网络配置

本章主要介绍网络配置的方法。 网络基础知识 查看网络信息 图形化界面修改 通过配置文件修改 命令行管理 11.1 网络基础知识 一台主机需要配置必要的网络信息&#xff0c;才可以连接到互联网。需要的配置网络信息包括IP、 子网掩码、网关和 DNS。 11.1.1 IP 地址 在计算机…

1.10 C语言之外部变量与作用域

1.10 C语言之外部变量与作用域 一、外部变量概述二、练习 一、外部变量概述 我们说&#xff0c;函数&#xff08;不管是main函数还是其他函数&#xff09;内部定义的变量&#xff0c;其作用范围都只在函数内部&#xff0c;我们把这些变量叫做自动变量或者局部变量。除了局部变…

嵌入式工程师校招经验与学习路线总结

前言&#xff1a;不知不觉2023年秋招已经结束&#xff0c;作者本人侥幸于秋招中斩获数十份大差不差的OFFER&#xff0c;包含&#xff1a;Top级的AIGC&#xff0c;工控龙头&#xff0c;国产MCU原厂&#xff0c;医疗器械&#xff0c;新能源车企等。总而言之&#xff0c;秋招总体情…

HarmonyOS开发工具DevEco Studio的下载和安装

一、DevEco Studio概述 一、下载安装鸿蒙应用开发工具DevEco Studio 开发鸿蒙应用可以从鸿蒙系统上运行第一个程序Hello World开始。 为了得到这个Hello World&#xff0c;你需要得到这个Hello World的源代码&#xff0c;源代码是用人比较容易看得懂的计算机编程语言规范写的…

leetcode做题笔记1466. 重新规划路线

n 座城市&#xff0c;从 0 到 n-1 编号&#xff0c;其间共有 n-1 条路线。因此&#xff0c;要想在两座不同城市之间旅行只有唯一一条路线可供选择&#xff08;路线网形成一颗树&#xff09;。去年&#xff0c;交通运输部决定重新规划路线&#xff0c;以改变交通拥堵的状况。 路…

排序:直接选择排序

直接选择排序&#xff1a; 本质&#xff1a; 直接选择排序的本质就是在数组中进行遍历挑选出最大的元素&#xff0c;讲最大的元素放到对应的位置后&#xff0c;再次选出次大的位置&#xff0c;而后又放到对应的位置..........................直到数组成为一个有序序列。 优…