【算法-数组2】有序数组的平方 和 长度最小的子数组

news2024/12/25 23:28:07

今天,带来数组相关算法的讲解。文中不足错漏之处望请斧正!

理论基础点这里


有序数组的平方

给你一个按 非递减顺序 排序的整数数组 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]

提示:

1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums 已按 非递减顺序 排序

进阶:

请你设计时间复杂度为 O(n) 的算法解决本问题

1. 思路

只有正数时,平方的大小就是从头到尾即由小到大。

在这里插入图片描述

那顺序遍历升序数组,作平方,就能得到升序结果。

但有负数时该怎么办?最小的平方应该是从两端趋向中间的最接近0的那个值。
在这里插入图片描述

从这个值往两边走,谁的平方大,谁就先插入结果集。题目要求升序,那我们就从结果集的尾部到结果集的头部放入结果。

要“往两边走”我们用双指针从两边遍历就好啦,谁大谁先插入结果数组。

2. 参考代码

class Solution {
public:
    // 找0, 双指针从两头向中间找, 平方和大的插入结果集的后面
    vector<int> sortedSquares(vector<int>& nums) {
        vector<int> result(nums.size());
        int left = 0;
        int right = nums.size() - 1;
        int insertIndex = result.size() - 1;

        while (left <= right) { // left==righrt时, nums[left]的平方和也要插入结果集
            long long squre1 = pow(nums[left], 2);
            long long squre2 = pow(nums[right], 2);
            if (squre1 > squre2) {
                result[insertIndex--] = squre1;
                ++left;
            } else {
                result[insertIndex--] = squre2;
                --right;
            }
        }

        return result;
    }
};

长度最小的子数组

1. 思路

理解题意

分析如何满足需求

1.1 暴力遍历

两层for,一个指针确定当前想遍历的区间的起始位置,另一个指针遍历来确定终止位置,把所有可能的区间都遍历一遍,一旦区间和大于target,就对比并取最小的长度。

参考代码如下:

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        int minLen = INT_MAX;
        int sum = 0; // 子序列的数值之和
        int subLength = 0; // 子序列的长度
        for (int i = 0; i < nums.size(); i++) { // 设置子序列起点为i
            sum = 0;
            for (int j = i; j < nums.size(); j++) { // 设置子序列终止位置为j
                sum += nums[j];
                if (sum >= s) { // 一旦发现子序列和超过了s,更新result
                    subLength = j - i + 1; // 取子序列的长度
                    result = result < subLength ? result : subLength;
                    break; // 因为我们是找符合条件最短的子序列,所以一旦符合条件就break,不要再累加元素了
                }
            }
        }
        return result == INT_MAX ? 0 : result;
    }
};

1.2 滑动窗口

暴力的方法比较死板:直接把所有可能得区间都遍历一遍。每一次都是静态确认好一个区间 [i, j] ,再累加求结果,有没有办法更灵活地确认这个连续子数组地区间呢?有的。

我们可以维护一个连续子数组的区间(右边的指针固定走,左边的指针能跟就跟,保证长度最小),——滑动窗口。

什么是滑动窗口?其实是双指针的一种应用,两个指针动态移动,维护一个区间,像滑动的窗口一样。

滑动窗口在本题中怎么用呢?

在这里插入图片描述

为什么是end固定往后走,begin根据策略走?

首先,end必须把整个数组遍历一遍;其次,begin作为起始位置,不一定需要固定走(如果区间和不大于等于target,走了有什么意义呢)。

end遍历给定数组nums,当区间和大于target的时候,就得到了当前最小的连续子序列但不是最终的。所以在end往后移动的时候,begin也要根据一定策略追赶end,保证得到最终的最小连续子序列。

begin到底是怎样移动的呢?
  • 如果当前区间是连续子数组,begin就要移动
  • 如果当前区间不是连续子数组,那么begin就不能移动

这样子移动,每次begin移动完,[begin, end]的和都会小于target(不再是连续子数组),但这不影响,因为在它最后还是连续子数组的时候,我们已经用minLen记录了它的长度。这样走下去,就能获取到最短的长度。

2. 参考代码

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int begin = 0; // [begin, end] 就是期望的最短子数组区间
        int end = 0;
        int curLen = 0;
        int minLen = INT_MAX;
        long long sum = 0;

        while (end < nums.size()) {
            sum += nums[end];
            while (sum >= target) { // 已经是子数组, 开始缩减长度
                curLen = end - begin + 1;
                minLen = min(curLen, minLen);
                sum -= nums[begin++]; // 缩减长度
            }
            ++end;
        }

        return minLen == INT_MAX ? 0 : minLen;
    }
};

今天的分享就到这里了,感谢您能看到这里。

这里是培根的blog,期待与你共同进步!

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

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

相关文章

多线程---阻塞队列+生产者消费者模型

文章目录 阻塞队列自己实现一个阻塞队列&#xff08;三步&#xff09;标准库中的阻塞队列使用阻塞队列的优势 生产者消费者模型 阻塞队列 队列&#xff08;Queue&#xff09;是我们熟悉的一个数据结构&#xff0c;它是“先进先出”的。但是并不是所有的队列都是“先进先出”的…

椭圆曲线在SM2加解密中的应用(三)

一、SM2加密运算 1.1加密原始数据 SM2加密运算首先是用户A对数据加密,用户A拥有原始数据 椭圆曲线系统参数长度为klen比特的消息M公钥Pb椭圆曲线系统参数,已经在 椭圆曲线参数(二)中详细介绍;M就是需要加密消息,长度为klen; 1.1.1 公钥Pb的计算方式 公钥Pb=dBG,其中…

【MySQL--->复合查询】

文章目录 [TOC](文章目录) 一、基本查询二、多表查询三、自连接四、子查询1. 单行子查询2. 多行查询3.多列子查询4.在from语句中使用子查询5.合并查询 一、基本查询 查询工资高于500或岗位为MANAGER的雇员&#xff0c;同时还要满足他们的姓名首字母为大写的J 按照部门号升序而…

C++进阶篇3---二叉搜索树(Binary Search Tree)

一、二叉搜索树的概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值 若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节点的值 它的…

java之输入与输出的详细介绍

文章目录 输出的相关格式使用 Scanner 类进行控制台输入步骤&#xff1a;示例&#xff1a; 如何格式化输出&#xff1f;1. 使用 System.out.printf2. 使用 String.format printf与println 的区别printfprintln主要区别&#xff1a; 输出的相关格式 控制台输入是指通过命令行或…

JAVA中的垃圾回收器(2)------G1

一)G1垃圾回收器:-XX:UseG1GC:使用G1收集器 1)垃圾收集器迭代停顿时间越少越好&#xff0c;但是垃圾回收的总时间会增多&#xff0c;默认暂停时间默认是200ms&#xff0c;G1的内部底层算法非常复杂比CMS复杂&#xff0c;如果大内存&#xff0c;G1还比较有效果&#xff0c;但是如…

leetcode-数组

1.二分法手撕704&#xff08;诀窍在于用合法区间判断&#xff09;230810 左闭右闭: while(left<right)合法&#xff0c;middle(leftright)/2, if(nums[middle]>target)说明nums[middle]一定不是我们搜索的值&#xff0c;所以rightmiddle-1; elseif(nums[middle]<targe…

基于单片机的太阳跟踪系统的设计

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 技术交流认准下方 CSDN 官方提供的联系方式 文章目录 概要 一、设计的主要内容二、硬件电路设计2.1跟踪控制方案的选择2.1.1跟踪系统坐标系的选择2.2系统总体设计及相关硬件介绍…

9、电路综合-基于简化实频的任意幅频响应的微带电路设计

9、电路综合-基于简化实频的任意幅频响应的微带电路设计 网络综合和简化实频理论学习概述中的1-8介绍了SRFT的一些基本概念和实验方法&#xff0c;终于走到了SRFT的究极用途&#xff0c;给定任意响应直接综合出微带电路。 1、任意幅频响应的微带电路设计用途 我们演示了采用…

Flask基本教程以及Jinjia2模板引擎简介

flask基本使用 直接看代码吧&#xff0c;非常容易上手&#xff1a; # 创建flask应用 app Flask(__name__)# 路由 app.route("/index", methods[GET]) def index():return "FLASK&#xff1a;欢迎访问主页&#xff01;"if __name__ "__main__"…

【多线程面试题九】、说一说sleep()和wait()的区别

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;说一说sleep()和wait()的…

如何使用 Docker 搭建 Jenkins 环境?从安装到精通

不少兄弟搭 jenkins 环境有问题&#xff0c;有的同学用 window, 有的同学用 mac&#xff0c; 有的同学用 linux。 还有的同学公司用 window, 家里用 mac&#xff0c;搭个环境头发掉了一地。。。 这回我们用 docker 去搭建 jenkins 环境&#xff0c;不管你是用的是什么系统&…

方太描画未来厨房的模样

作者 | 辰纹 来源 | 洞见新研社 不知不觉中&#xff0c;iPhone已经更新到15代了&#xff0c;家里的电视变成了越来越轻薄的液晶屏&#xff0c;过去被称为“老三样”的富康&#xff0c;捷达、桑塔纳&#xff0c;如今也被以特斯拉为代表的新能源智能汽车们所取代…… 类似以上的…

第五章 I/O管理 一、I/O设备的基本概念和分类

目录 一、什么是I/O设备 1、定义&#xff1a; 2、按特性分类&#xff1a; 3、按传输速率分类&#xff1a; 4、按信息交换的方式分类&#xff1a; 二、总结 一、什么是I/O设备 1、定义&#xff1a; I/O设备就是可以将数据输入到计算机&#xff0c;或者可以接收计算机输出…

<C++> vector模拟实现

目录 前言 一、定义命名空间 二、构造函数 三、拷贝构造 四、赋值运算符重载 五、push_back && reserve 六、深拷贝问题 七、iterator 迭代器 1. 可读可写 2. 只读 八、operator[ ] 1. 可读可写 2. 只读 九、insert 问题&#xff1a;内部迭代器失效 十、erase 十一、re…

【网络安全】Seeker内网穿透追踪定位

Seeker追踪定位对方精确位置 前言一、kali安装二、seeker定位1、ngrok平台注册2、获取一次性邮箱地址3、ngrok平台登录4、ngrok下载5、ngrok令牌授权6、seeker下载7、运行seeker定位8、运行隧道开启监听9、伪装链接10、用户点击&#xff08;获取定位成功&#xff09;11、利用经…

(速进)完美解决“用户在命令行上发出了 EULAS_AGREED=1,表示不接受许可协议。”以及“此产品安装程序不支持降级”

安装VMware时候&#xff0c;出现以下两种情况的原因是&#xff1a;未彻底卸载&#xff08;之前安装过VMware&#xff09;&#xff0c;例如&#xff1a;还有相关配置信息、注册表信息等。只要彻底清理就可以解决此问题。 网上很多帖子使用了powershell里的命令 例如&#xff1…

Linux病毒疯狂增长,我们该如何…

导读国家信息中心日前与瑞星联合发布的《2017年上半年中国网络安全报告》&#xff08;以下简称《报告》&#xff09;指出&#xff0c;目前Linux系统病毒已快速增长。《报告》对2017年1至6月的网络安全现状与趋势进行统计、研究和分析后指出&#xff0c;Linux系统的勒索软件数量…

帆软finereport10.0 多个筛选框根据不同条件必须选一个才能查询

效果&#xff1a; 方法一&#xff1a; 方法二&#xff1a; 方法一&#xff1a;在查询里写上一段js&#xff0c;此方法会把端口和IP暴露出来&#xff0c;方法二比较完美。 var diff this.options.form.getWidgetByName("diff").getValue();//正反向 var fllh …

【多线程面试题 八】、说一说Java同步机制中的wait和notify

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;说一说Java同步机制中的…