【每日一道算法题】有序数组的平方、长度最小的子数组

文章目录

      • 有序数组的平方
        • 写在前面
        • 题目
        • 思路解析
          • 暴力解法
          • 双指针法
        • 我的代码
          • 暴力解法
          • 双指针法
        • 参考答案解法
          • 暴力方法
          • 双指针法
      • 长度最小的子数组
        • 原题
        • 思路解析
          • 暴力法
          • 滑动窗口法
        • 我的代码
        • 官方题解
          • 滑动窗口法

有序数组的平方

写在前面

本人是一名在java后端寻路的小白,希望记录此博客来帮助自己理解和日后复习,希望也能够帮助到你。

题目

力扣题目链接

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

示例 1:

  • 输入:nums = [-4,-1,0,3,10]
  • 输出:[0,1,9,16,100]
  • 解释:平方后,数组变为 [16,1,0,9,100],排序后,数组变为 [0,1,9,16,100]

示例 2:

  • 输入:nums = [-7,-3,2,3,11]
  • 输出:[4,9,9,49,121]
思路解析
暴力解法

这道题目给了一个数组,当中的元素是非递减的(非递减表示元素可能递增,也可能当中有重复值,不算严格的递增),要求把元素进行平方,并且也进行非递减排序。

最容易想到的方法,也就是暴力解法,就是将每个元素进行平方,然后对平方后得到的数组使用Arrays类当中的sort方法直接进行排序。

但是一瞬间竟不知如何返回数组的平方。。菜狗如我

双指针法

采用双指针是因为数组平方之后,最大值最有可能出现在数组两端,最不可能出现在数组中间。(因为数组是非递减的,而且存在负数,所以在平方之后最大值肯定出现在两端)。根据这个想法,我们可以采用双指针,一个指针start指向起始索引,一个指针end指向末尾索引,然后判断这两个指针指向的数哪一个的平方更大,指针指向的元素的平方更大的一者用倒序添加的方式添加到新数组的末尾,然后该指针向中间移动一位,另一个指针不动,继续进行下一次比较。

我的代码
暴力解法
class Solution {public int[] sortedSquares(int[] nums) {//先创建新的数组,长度等同于旧数组int[] newArr = new int[nums.length];//对旧数组中的元素进行平方,然后赋值给新数组的对应位置上的元素for(int i = 0; i < nums.length; i++){newArr[i] = nums[i]*nums[i];}//直接调用类Arrays中的sort方法对新数组进行排序Arrays.sort(newArr);//返回新数组return newArr;}
}
双指针法
class Solution {public int[] sortedSquares(int[] nums) {//双指针法,一个指针i指向数组的起始索引,一个指针j指向数组的末尾索引length-1int i = 0;int j = nums.length - 1;int k = nums.length - 1;//定义一个新数组,长度等于老数组int[] newArr = new int[nums.length];//指针移动的循环结束条件,两者相遇表示最后一个元素,此时这个元素是需要写入新数组中的while(i <= j){//比较两个指针指向的元素的平方//假如i指针指向元素的平方更大,那么将其写进新数组的末尾元素,i指针向后移动,j指针不动if(nums[i]*nums[i] > nums[j]*nums[j]){newArr[k] = nums[i]*nums[i];i++;k--;}//假如j指针指向元素的平方更大或者相等,那么将其写进新数组的末尾元素,j指针向前移动,i指针不动else{newArr[k] = nums[j]*nums[j];j--;k--;}}return newArr;}
}
参考答案解法
暴力方法
class Solution {public int[] sortedSquares(int[] nums) {int[] ans = new int[nums.length];for (int i = 0; i < nums.length; ++i) {ans[i] = nums[i] * nums[i];}Arrays.sort(ans);return ans;}
}
双指针法
class Solution {public int[] sortedSquares(int[] nums) {int n = nums.length;int[] ans = new int[n];for (int i = 0, j = n - 1, pos = n - 1; i <= j;) {if (nums[i] * nums[i] > nums[j] * nums[j]) {ans[pos] = nums[i] * nums[i];++i;} else {ans[pos] = nums[j] * nums[j];--j;}--pos;}return ans;}
}

长度最小的子数组

原题

力扣题目链接

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

示例 1:

  • 输入:nums = [-4,-1,0,3,10]
  • 输出:[0,1,9,16,100]
  • 解释:平方后,数组变为 [16,1,0,9,100],排序后,数组变为 [0,1,9,16,100]

示例 2:

  • 输入:nums = [-7,-3,2,3,11]
  • 输出:[4,9,9,49,121]
思路解析
暴力法

这题我没有采用暴力法,直接采用了滑动窗口(感觉滑动窗口的思想反而更直观一些)。暴力法是用两次for循环,初始化子数组的最小长度为无穷大,第一个for循环遍历数组 nums 中的每个下标作为子数组的开始下标,对于每个开始下标 i,需要找到大于或等于 i 的最小下标 j,使得从 nums[i] 到 nums[j]的元素和大于或等于 s,并更新子数组的最小长度(此时子数组的长度是 j−i+1)

滑动窗口法

滑动窗口其实就是双指针的变种。窗口其实就是一个连续的子数组,定义两个指针,一个指针start指向窗口的开始索引,一个指针end指向窗口的末尾索引,这两个指针最开始都指向数组的0索引。

滑动窗口法的过程就是,end指针通过一个for循环遍历逐步扩大窗口,start指针保持不动,end每扩大一次,就判断start~end窗口当中的元素总和是否大于目标值target。如果窗口的总和大于目标值,那么start指针就往前移动一位,目的是寻找是否存在潜在的长度更小的而且符合要求的子数组。

怎么求窗口的元素和,这里也是我当时临时想出来的。就是在一开始定义一个变量sum,表示窗口元素的总和。在end指针往前走、而start指针保持不动的时候,每当end向前走一位、窗口扩大一格的时候,窗口元素的总和就往前追加;而每次start往前走一位,窗口元素的总和就减去原来start指针指向的那个元素。

我的代码

我忘记考虑了数组长度为0的情况,这时候需要直接返回0。

class Solution {public int minSubArrayLen(int target, int[] nums) {//滑动窗口解法,定义窗口的起始指针和末尾指针int i = 0;int j = 0;//定义一个变量来存储窗口的和int sum = 0;//定义一个变量记录最小的窗口长度int shortest = nums.length + 1;//用一个for循环中的i指针表示窗口的末尾索引,用j指针表示窗口的起始索引for(i = 0; i < nums.length; i++){sum = sum + nums[i];//判断窗口当中所有元素的和是否大于等于目标值while(sum >= target){//窗口元素和大于目标值//判断,如果窗口的长度=1,说明此时是最小长度,直接返回1if(i-j+1 == 1){return 1;}//如果子数组的长度不是1,说明还可能存在潜在的最小窗口长度,此时j++else{//如果此时窗口长度小于最小窗口长度,则将此时窗口的长度赋值给最小长度if(i-j+1 < shortest){shortest = i-j+1;}sum = sum - nums[j];j++;}}//如果窗口之和不符合条件,则i继续++,然后给窗口之和加上i指向的最新的值,随后继续判断}if(shortest == nums.length + 1){return 0;}return  shortest;   }
}
官方题解
滑动窗口法
class Solution {public int minSubArrayLen(int s, int[] nums) {int n = nums.length;if (n == 0) {return 0;}int ans = Integer.MAX_VALUE;int start = 0, end = 0;int sum = 0;while (end < n) {sum += nums[end];while (sum >= s) {ans = Math.min(ans, end - start + 1);sum -= nums[start];start++;}end++;}return ans == Integer.MAX_VALUE ? 0 : ans;}
}

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

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

相关文章

JAV八股--redis

如何保证Redis和数据库数据一致性 关于异步通知中消息队列和Canal的内容。 redisson实现的分布式锁的主从一致性 明天继续深入看这个系列问题 介绍IO复用模型

【机器学习300问】59、计算图是如何帮助人们理解反向传播的?

在学习神经网络的时候&#xff0c;势必会学到误差反向传播&#xff0c;它对于神经网络的意义极其重大&#xff0c;它是训练多层前馈神经网络的核心算法&#xff0c;也是机器学习和深度学习领域中最为重要的算法之一。要正确理解误差反向传播&#xff0c;不妨借助一个工具——计…

代码随想录算法训练营第24天|理论基础 |77. 组合

理论基础 jia其实在讲解二叉树的时候&#xff0c;就给大家介绍过回溯&#xff0c;这次正式开启回溯算法&#xff0c;大家可以先看视频&#xff0c;对回溯算法有一个整体的了解。 题目链接/文章讲解&#xff1a;代码随想录 视频讲解&#xff1a;带你学透回溯算法&#xff08;理…

第22章-路由协议概述

1. 定义 2. 路由协议的功能 3. 路由协议的分类 1. 定义 1)概述: 路由协议(Routing Protocol):计算、维护路由信息的协议; 功能:根据相应的算法产生路由,确定路由的有效性,维护路由; 常见路由协议:RIP、OSPF、BGP等; 2)路由协议与可路由协议 路由协议:实现路由选择的…

gpt的构造和原理

gpt是序列预测模型。 问答是通过确定问答格式样本训练出来的&#xff01;比如“Q&#xff1a;xxxx.A:xxx"本质还是根据前面的序列预测后面的序列。在自回归训练过程中&#xff0c;文本序列&#xff08;可能包含问题和紧随其后的答案&#xff09;被视为一个整体输入到模型…

深入理解数据结构——堆

前言&#xff1a; 在前面我们已经学习了数据结构的基础操作&#xff1a;顺序表和链表及其相关内容&#xff0c;今天我们来学一点有些难度的知识——数据结构中的二叉树&#xff0c;今天我们先来学习二叉树中堆的知识&#xff0c;这部分内容还是非常有意思的&#xff0c;下面我们…

前端秘法番外篇----学完Web API,前端才能算真正的入门

目录 一.引言 二.元素的获取和事件 1.获取元素 2.各种事件 2.1点击事件 2.2键盘事件 三.获取&修改操作 1.获取修改元素属性 2.修改表单属性 2.1暂停播放键的转换 2.2计数器的实现 2.3全选的实现 3.样式操作 3.1行内样式操作 3.2类名样式操作 四.节点 1.创…

记录Xshell使用ed25519公钥免密链接SSH

试了半天&#xff0c;Xshell好像没办法导入linux生成的ssh公钥,因此需要以下步骤实现免密登录 结论&#xff0c;在linux公钥文件中&#xff0c;将客户端生成的ed25519公钥加上去即可(一个公钥单独一行) 1.使用Linux生成秘钥文件(不需要输入私钥密码passphrase)或者直接创建一…

【Servlet】继承关系以及service方法

文章目录 一、继承关系二、相关方法 一、继承关系 Servlet接口下有一个GenericServlet抽象类。在GenericServlet下有一个子类HttpServlet&#xff0c;它是基于http协议。 继承关系 javax.servlet.Servlet接口​ javax.GenericServlet抽象类​ javax.servlet.http.HttpServ…

生产制造园区数字孪生3D大屏展示提升运营效益

在智慧园区的建设中&#xff0c;3D可视化管理平台成为必不可少的工具&#xff0c;数字孪生公司深圳华锐视点打造的智慧园区3D可视化综合管理平台&#xff0c;致力于将园区的人口、经济、应急服务等各项业务进行3D数字化、网络化处理&#xff0c;从而实现决策支持的优化和管理的…

C++多线程:Atomic原子类与CAS锁详解(十)

1、原子操作的概念 什么是原子操作&#xff1a; 原子被认为是构成物质最小的单位&#xff0c;是不可分割的一个东西。而在程序中原子操作被认为是不可分割的一个步骤或者指令其实我们很简单的程序&#xff0c;在高级语言中被认为是一个步骤的操作&#xff0c;编译成汇编指令之…

Redis从入门到精通(三)Jedis客户端、SpringDataRedis客户端

文章目录 前言第3章 Redis的Java客户端3.1 Jedis客户端3.1.1 快速使用3.1.2 连接池 3.2 SpringDataRedis客户端3.2.1 快速使用3.2.2 自定义序列化3.2.3 StringRedisTemplate 3.3 小结 前言 在上一章【Redis从入门到精通(二)Redis的数据类型和常见命令介绍】中&#xff0c;学习…

Springboot+MybatisPlus+EasyExcel实现文件导入数据

记录一下写Excel文件导入数据所经历的问题。 springboot提供的文件处理MultipartFile有关方法&#xff0c;我没有具体看文档&#xff0c;但目测比较复杂&#xff0c; 遂了解学习了一下别的文件上传方法&#xff0c;本文第1节记录的是springboot原始的导入文件方法写法&#xf…

docker-compse安装es(包括IK分词器扩展)、kibana、libreoffice

Kibana是一个开源的分析与可视化平台&#xff0c;设计出来用于和Elasticsearch一起使用的。你可以用kibana搜索、查看存放在Elasticsearch中的数据。 Kibana与Elasticsearch的交互方式是各种不同的图表、表格、地图等&#xff0c;直观的展示数据&#xff0c;从而达到高级的数据…

MySQL 优化及故障排查

目录 一、mysql 前置知识点 二、MySQL 单实例常见故障 故障一 故障二 故障三 故障四 故障五 故障六 故障七 故障八 三、MySQL 主从故障排查 故障一 故障二 故障三 四、MySQL 优化 1.硬件方面 &#xff08;1&#xff09;关于 CPU &#xff08;2&#xff09;关…

前端低代码平台的使用学习

背景 最近发现老婆每天都要捣鼓一个 excel 表格&#xff0c;并将表格发到群中&#xff0c;询问后才知道只是为了记录每天的事物变化。我想这接收方每次都要下载表格再打开看&#xff0c;太麻烦了&#xff0c;直接做个 web 表单&#xff0c;支持简单的增删改查就好了。 当我着手…

【Gradle 一】Gradle入门简介(Maven/Gradle比较、Gradle目录结构常用命令)

1.maven与gradle的比较&#xff1a; 侧重点&#xff1a;同样作为项目构建工具&#xff0c;maven侧重于项目jar包管理&#xff0c;gradle侧重于项目的构建构建性能&#xff1a;gradle远高于maven 2.maven目录结构&#xff1a; target classes src main javaresources test ja…

Reversing Linked List

Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K3, then you must output 3→2→1→6→5→4; if K4, you must output 4→3→2→1→5→6. Input Specifi…

网络基础——ISIS

名词 ISIS&#xff1a;中间系统到中间系统&#xff0c;优先级是15集成化ISIS&#xff1a;这是在优化后&#xff0c;可以使用在OSI模型上的NET地址&#xff1a;由区域ID、系统ID和SEL组成&#xff0c;一台设备上最多配置3个NET地址&#xff0c;条件是区域号要不一致&#xff0c;…

Intel FPGA (7):adc adc128s102

Intel FPGA (7)&#xff1a;adc adc128s102 前提摘要 个人说明&#xff1a; 限于时间紧迫以及作者水平有限&#xff0c;本文错误、疏漏之处恐不在少数&#xff0c;恳请读者批评指正。意见请留言或者发送邮件至&#xff1a;“Email:noahpanzzzgmail.com”。本博客的工程文件均存…