【算法刷题 | 数组】3.12(二分查找、移除元素、有序数组的平方、长度最小的子数组、螺旋矩阵2)

文章目录

  • 1.二分查找
    • 1.1题目
    • 1.2思路(核心:区间的定义)
    • 1.3左闭右闭
    • 1.4左闭右开
    • 1.5总结
  • 2.移除元素
    • 2.1题目
    • 2.1思路
      • 2.2.1暴力解法
      • 2.2.2双指针法
    • 23总结
  • 3.有序数组的平方
    • 3.1题目
    • 3.2思路
      • 3.2.1暴力解法
      • 3.2.2双指针法
  • 4.长度最小的子数组
    • 4.1题目
    • 4.2思路
      • 4.2.1暴力解法
      • 4.2.2滑动窗口(双指针升级)
  • 5.螺旋矩阵2
    • 5.1题目
    • 5.2思路

1.二分查找

1.1题目

704.二分查找—力扣题目链接

  • 题目:给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1
  • 示例一:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
  • 示例二:
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1

1.2思路(核心:区间的定义)

  1. 题目的前提是数组为有序数组,同时题目还强调 数组中无重复元素
  2. 因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的,这些都是使用二分法的前提条件,当大家看到题目描述满足如上条件的时候,可要想一想是不是可以用二分法了。

1.3左闭右闭

  • 定义target在 [left, right] 区间,所以有如下两点:
  1. while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=
  2. if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1
  3. 下面举例演示:在一组有序,不重复数组中分别查找数据2、数据6的过程

image-20240310152650608

/*** @Description 二分查找第一种写法:左闭右闭* @Param* @Return 下标值:int*/public int binarySearch1(int[] arr,int target){int left=0;int right=arr.length-1;while(left<=right){/***  写法一:可能出现溢出情况*      int mid=(left+right)/2;*  写法二:*      int mid=left+(right-left)/2;*///写法三:右移运算符 代替 除号int mid=left+((right-left)>>1);if(arr[mid]>target){        //在左区间,即[left,mid-1]right=mid-1;}else if(arr[mid]<target){  //在右区间,即[mid+1,right]left=mid+1;}else{return mid;}}return -1;}
  • 时间复杂度:O(log n)
  • 空间复杂度:O(1)

1.4左闭右开

如果说定义 target 是在一个在左闭右开的区间里,也就是[left, right) ,那么二分法的边界处理方式则截然不同。

  1. while (left < right),这里使用 < ,因为left == right在区间[left, right)是没有意义的
  2. if (nums[middle] > target) right 更新为 middle,因为当前nums[middle]大于target,去左区间继续寻找,而寻找区间是左闭右开区间,所以right更新为middle,即:下一个查询区间不会去比较nums[middle]

image-20240310155356483

  • 代码示例:
	/*** @Description 二分查找第一种写法:左闭右闭* @Param* @Return 下标值:int*/public int binarySearch2(int[] arr,int target){int left=0;int right=arr.length;while(left<right){int mid=left+((right-left)>>1);if(arr[mid]>target){        //在左区间,即[left,mid-1)right=mid;}else if(arr[mid]<target){  //在右区间,即[mid+1,righ)left=mid+1;}else{return mid;}}return -1;}
  • 时间复杂度:O(log n)
  • 空间复杂度:O(1)

1.5总结

  • 使用二分查找的两个前提:
    • 数组有序
    • 数组元素唯一,不重复
  • 二分查找的两个写法区分:
左闭右闭左闭右开
right初始取值right=arr.length-1right=arr.length
循环条件while(left<=right)while(left<right)
left更新值(到右区间查找)left=mid+1left=mid+1
right更新值(到左区间查找)right=mid-1right=mid

2.移除元素

27.移除元素_力扣链接

2.1题目

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

  • 示例1:
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。
  • 示例2:
输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,3,0,4]
解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。

2.1思路

2.2.1暴力解法

两层for循环,一个for循环遍历数组元素 ,第二个for循环更新数组。

27.移除元素-暴力解法

class Solution {public int removeElement(int[] nums, int val) {int total=0;for(int i=0;i<nums.length;i++){if(nums[i]==val){//发现该val值,将该位置后面的数组都往前移动一位for(int j=i+1;j<nums.length;j++){nums[j-1]=nums[j];}i--;//结束内层循环后,执行i++命令,但是原来的nums[i+1]位置上的元素已经被覆盖为nums[i+2]total++;}}return nums.length-total;}
}

2.2.2双指针法

  • 定义:通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
    • 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
    • 慢指针:指向更新 新数组下标的位置
  • 演示:

27.移除元素-双指针法

  • 代码:
class Solution {public int removeElement(int[] nums, int val) {int total=0;//快慢指针int slowIndex=0;for(int fastIndex=0;fastIndex<nums.length;fastIndex++){if(nums[fastIndex]!=val){//将快指针的值赋予慢指针的值,并同时向前移动nums[slowIndex]=nums[fastIndex];slowIndex++;}else{//找到该值,暂停慢指针total++;}}return nums.length-total;}
}
  • 注意这些实现方法并没有改变元素的相对位置!
    • 时间复杂度:O(n)
    • 空间复杂度:O(1)

23总结

双指针法(快慢指针法)在数组和链表的操作中是非常常见的,很多考察数组、链表、字符串等操作的面试题,都使用双指针法。

3.有序数组的平方

3.1题目

977.有序数组的平方——力扣题目链接

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

  • 示例一:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]
  • 示例二:
输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]

3.2思路

3.2.1暴力解法

  • 遍历数组,将数组的每个元素平方,接着排个序即可

3.2.2双指针法

  • 原数组是 有序 的,就是说数字0的左区间(平方后的元素,越左边,越大)、右区间(平方后的元素,越右边,越大)

  • 由此可以得出平方后的数组最大值不是在原数组最左边,就是最右边

  • 考虑双指针法了,i指向起始位置,j指向终止位置

  • 示意图:

    img

class Solution {public int[] sortedSquares(int[] nums) {//思路:原数组有序,那最大值不是在最左边,就是在最右边//双指针:分别指向最左边和最右边,并新建一个数组,将最大值移向数组的最后面int len=nums.length;int j=nums.length-1;int k=nums.length-1;int[] arr=new int[len];for(int i=0;i<=j;i++){      //循环条件 i<=j,最后要处理最后一个元素if(nums[i]*nums[i]>nums[j]*nums[j]){// i位置的元素的绝对值大arr[k--]=nums[i]*nums[i];}else{// j位置的元素的绝对值大arr[k--]=nums[j]*nums[j];i--;    //i保持不动j--;}}return arr;}
}

4.长度最小的子数组

4.1题目

给定一个含有 n 个正整数的数组和一个正整数 target

找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度**。**如果不存在符合条件的子数组,返回 0

  • 示例一:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
  • 示例二:
输入:target = 4, nums = [1,4,4]
输出:1
  • 示例三:
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0

4.2思路

4.2.1暴力解法

  • 解法一:暴力解法,两层for循环,第一层为子序列的起始位置,第二层为子序列的终点位置
  • 在第二层中,逐渐累加子序列的值,若发现>=target,则与原来的子序列长度比较,是否需要替换
class Solution {public int minSubArrayLen(int target, int[] nums) {int min=Integer.MAX_VALUE;  //子序列的值int sum=0;for(int i=0;i<nums.length;i++){     //i为起始位置sum=0;                          //重置sum=0for(int j=i;j<nums.length;j++){ //j为终点位置sum+=nums[j];if(sum>=target){min=min>(j-i+1)?(j-i+1):min;    //更新子序列的长度}}}return min==Integer.MAX_VALUE?0:min;}
}

4.2.2滑动窗口(双指针升级)

  • 解法二:滑动窗口
    • 问题:如何使用一个for循环,就能确定子序列的起始、终点位置
    • 解决 :动态更改子序列的起始位置for循环确定子序列的终点位置
    • 只要当sum>=target,第一更新子序列长度的值,第二滑动子序列的起始位置(先更新子序列总和,再滑动)
    • 209.长度最小的子数组
class Solution {public int minSubArrayLen(int target, int[] nums) {int min=Integer.MAX_VALUE;int sum=0;int i=0;                                //i为起始位置for(int j=0;j<nums.length;j++){         //j为终点位置sum+=nums[j];while(sum>=target){//1、更新子序列的长度min=min>(j-i+1)?(j-i+1):min;//2、滑动起始位置:先减去初始位置的值,再滑动sum-=nums[i];i++;}}return min==Integer.MAX_VALUE?0:min;}
}

5.螺旋矩阵2

5.1题目

59. 螺旋矩阵 II

给你一个正整数 n ,生成一个包含 1n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix

  • 示例一:

    img

输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
  • 示例二:
输入:n = 1
输出:[[1]]

5.2思路

  • 每次赋值可分为4次:上、右、下、左

  • 首先明确每次赋值,确保都是==左闭右开==(即1 2;3 4;5 6;7 8)

img

  • 循环的圈数:loop=n/2;n为3时循环一圈;n为4时循环两圈
  • n为奇数,则最后中间还有个值,arr(n/2)(n/2)
  • 每次循环过后,右边界都要缩小一格
  • 注意每次循环过后,起始点的位置!!!
class Solution {public int[][] generateMatrix(int n) {int loop=n/2;int count=1;int[][] arr=new int[n][n];int start=0;                //每次循环的开始点(start,start)int i=0;int j=0;int offset=1;               //每次循环右边界收缩一位,控制每条边的遍历长度for(int k=0;k<loop;k++){    //k表示正在循环的圈数i=start;                //更新起始点j=start;//上:从左到右for(j=start;j<n-offset;j++){arr[i][j]=count++;}//右:从上到下for(i=start;i<n-offset;i++){arr[i][j]=count++;}//下:从右到左for(;j>start;j--){arr[i][j]=count++;}//左:从下到上for(;i>start;i--){arr[i][j]=count++;}start++;    //循环起始点加一offset++;}if (n % 2 == 1) {arr[n/2][n/2] = count;}return arr;}
}

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

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

相关文章

Linux中文件和目录管理(创建删除移动复制)

目录 1——一次建立一个或多个目录&#xff1a;mkdir ​2——创建一个空文件&#xff1a;touch 3——移动和重命名&#xff1a;mv 4——复制文件和目录&#xff1a;cp 5—— 删除目录和文件&#xff1a;rmdir和rm 在学习文件与目录的管理的一些命令之前&#xff0c;我们先…

深度学习-面经(part2、CNN)

2 CNN 对图像&#xff08;不同的数据窗口数据&#xff09;和滤波矩阵做内积&#xff08;逐个元素相乘再求和&#xff09;的操作就是所谓的『卷积』操作。 卷积神经网络由输入层、卷积层、激励层、池化层、全连接层组成。 ① 最左边: 数据输入层&#xff0c;对数据做一些处理…

数字后端 EDA 软件分享

数字后端 EDA 软件分享 推荐这几家的EDA工具吧&#xff0c;虽说我也支持国产工具&#xff0c;但是我还是选择了这几家的工具 apache cadence mentor synopsys 下图我现在用的eda环境&#xff0c;利用网上的资源&#xff0c;自己独立在vmware上搭建好的EDA环境 除去pdk&#…

从政府工作报告探究计算机行业发展

从政府工作报告探计算机行业发展 政府工作报告作为政府工作的全面总结和未来规划&#xff0c;不仅反映了国家整体的发展态势&#xff0c;也为各行各业提供了发展的指引和参考。随着信息技术的快速发展&#xff0c;计算机行业已经成为推动经济社会发展的重要引擎之一。因此&…

计算机考研|怎么备考「科软」?

学好408和考研数学就可以了 大家对于科软已经回到了理性的区间&#xff0c;很难再出现刚开始的300分上科软的现象&#xff0c;也不会再出现388分炸穿地心的现象。 如果大家想报考科软&#xff0c;我觉得一定要认真对待复习&#xff0c;不要抱有抄底的心态去复习。 众所周知&am…

7.JavaWebHTML:构建数字世界的语言和结构

目录 导语&#xff1a; 第一部分&#xff1a;Web概念与作用 1.1 Web的定义 1.2 Web的作用 1.3 JavaWeb 第二部分&#xff1a;HTML概念与内容 2.1 HTML的定义 2.2 HTML的内容 第三部分&#xff1a;HTML的作用 3.1 HTML的作用 3.2 HTML在现代Web开发中的角色 …

[Redis]——主从同步原理(全量同步、增量同步)

目录 Redis集群&#xff1a; 主从同步原理&#xff1a; replid和offset: 全量同步和增量同步&#xff1a; repl_baklog文件&#xff1a; 主从集群的优化&#xff1a; Redis集群&#xff1a; 部署多台Redis我们称之为Redis集群&#xff0c;他有一个主节点(负责写操作)&…

爱普生晶振发布RTC模块晶振(压电侠)

爱普生晶振一直以”省&#xff0c;小&#xff0c;精”技术作为资深核心&#xff0c;并且已经建立了一个原始的垂直整合制造模型&#xff0c;可以自己创建独特的核心技术和设备&#xff0c;使用这些作为基地的规划和设计提供独特价值的产品. 世界领先的石英晶体技术精工爱普生公…

中国联通智慧矿山行业解决方案

中国联通国际公司以其全球化服务能力&#xff0c;针对矿山行业的特殊挑战提供了定制化的解决方案&#xff0c;尤其是在网络通信基础设施搭建和智能应用部署方面&#xff0c;助力企业克服远程作业环境下的通信难题&#xff0c;并有效拓展海外市场。 对于矿山类企业而言&#xf…

【遍历方法】浅析Java中字符串、数组、集合的遍历

目录 前言 字符串篇 1.1 使用 for 循环和 charAt 方法 1.2 使用增强 for 循环&#xff08;forEach 循环&#xff09; 1.3 使用 Java 8 的 Stream API 最终效果 数组篇 2.1 使用普通 for 循环 2.2 使用增强型 for 循环( forEach 循环) 2.3 使用 Arrays.asList 和 forE…

解决:springboot项目访问hdfs文件提示guava版本不兼容

1、问题描述 版本说明&#xff1a;我用的hadoop版本&#xff1a;3.1.3 项目可以正常启动&#xff0c;但是调用访问hdfs的服务时候报错,报错消息如下&#xff1a;com.google.common.base.preconditions.checkArgument(ZL java/lang/String;Ljava/lang/Object:)V 原因分析&#x…

Flutter开发进阶之使用工具效率开发

Flutter开发进阶之使用工具效率开发 软件开发团队使用Flutter开发的原因通常是因为Flutter开发性能高、效率高、兼容性好、可拓展性高&#xff0c;作为软件PM来说主要考虑的是范围管理、进度管理、成本管理、资源管理、质量管理、风险管理和沟通管理等&#xff0c;可以看到Flu…

企业内部培训考试系统培训计划功能说明

培训计划是预设好的一套课程系列&#xff0c;包含课程和考试&#xff0c;分多个阶段&#xff0c;每完成一个阶段就会在学习地图上留下标记&#xff0c;让用户看到自己的努力成果&#xff0c;增强成就感&#xff0c;从而坚持完成课程。 企业内部培训考试系统中如何设置培训计划…

基于springboot的购物商城管理系统

1.项目简介 1.1 用户简介 用户主要分为管理员和用户端&#xff1a; 管理员&#xff1a; 管理员可以对后台数据进行管理、拥有最高权限、具体权限有登录后进行首页轮播图的配置管理、商品的配置、新品家具商城的配置管理、、家具商城分类管理配置、家具商城详情商品管理、用户…

react-面试题

一、组件基础 1. React 事件机制 <div onClick{this.handleClick.bind(this)}>点我</div> React并不是将click事件绑定到了div的真实DOM上&#xff0c;而是在document处监听了所有的事件&#xff0c;当事件发生并且冒泡到document处的时候&#xff0c;React将事…

网络安全JavaSE第二天(持续更新)

3. 基本数据与运算 3.6 运算符 3.6.1 算术运算符 在 Java 中&#xff0c;算术运算符包含&#xff1a;、-、*、/、% public class ArithmeticOperator { public static void main(String[] args) { int a 10; // 定义了一个整型类型的变量 a&#xff0c;它的值是 10 int b …

区块链推广海外市场怎么做,CloudNEO服务商免费为您定制个性化营销方案

随着区块链技术的不断发展和应用场景的扩大&#xff0c;区块链项目希望能够进入海外市场并取得成功已成为越来越多公司的目标之一。然而&#xff0c;要在海外市场推广区块链项目&#xff0c;需要采取有效的营销策略和措施。作为您的区块链项目营销服务商&#xff0c;CloudNEO将…

后端程序员入门react笔记(八)-redux的使用和项目搭建

一个更好用的文档 添加链接描述 箭头函数的简化 //简化前 function countIncreAction(data) {return {type:"INCREMENT",data} } //简化后 const countIncreAction data>({type:"INCREMENT",data })react UI组件库相关资料 组件库连接和推荐 antd组…

Python 多线程大批量处理文件小程序

说明 平时偶尔需要进行重复性的对文件进行重命名、格式转化等。假设以文件复制功能作为目标&#xff0c;设计一个小程序使用多线程对文件进行批量复制。&#xff08;其实以后主要目标是针对Realsense的raw文件进行批量的转化&#xff0c;并借助多线程加速&#xff09; 代码 i…

uv 必备的工具 ps ai 全家桶合集

非常稀有的资源 &#xff0c;必应搜索 易品资源yipinziyuan 可以找到