1630.等差子数组

1630. 等差子数组

难度中等

如果一个数列由至少两个元素组成,且每两个连续元素之间的差值都相同,那么这个序列就是 等差数列 。更正式地,数列 s 是等差数列,只需要满足:对于每个有效的 i , s[i+1] - s[i] == s[1] - s[0] 都成立。

例如,下面这些都是 等差数列 :

1, 3, 5, 7, 9
7, 7, 7, 7
3, -1, -5, -9

下面的数列 不是等差数列 :

1, 1, 2, 5, 7

给你一个由 n 个整数组成的数组 nums,和两个由 m 个整数组成的数组 l 和 r,后两个数组表示 m 组范围查询,其中第 i 个查询对应范围 [l[i], r[i]] 。所有数组的下标都是 从 0 开始 的。

返回 boolean 元素构成的答案列表 answer 。如果子数组 nums[l[i]], nums[l[i]+1], ... , nums[r[i]] 可以 重新排列 形成 等差数列 ,answer[i] 的值就是 true;否则answer[i] 的值就是 false 。

示例 1:

输入:nums = [4,6,5,9,3,7], l = [0,0,2], r = [2,3,5]
输出:[true,false,true]
解释:
第 0 个查询,对应子数组 [4,6,5] 。可以重新排列为等差数列 [6,5,4] 。
第 1 个查询,对应子数组 [4,6,5,9] 。无法重新排列形成等差数列。
第 2 个查询,对应子数组 [5,9,3,7] 。可以重新排列为等差数列 [3,5,7,9] 。

示例 2:

输入:nums = [-12,-9,-3,-12,-6,15,20,-25,-20,-15,-10], l = [0,1,6,4,8,7], r = [4,4,9,7,9,10]
输出:[false,true,false,false,true,true]

提示:

  • n == nums.length
  • m == l.length
  • m == r.length
  • 2 <= n <= 500
  • 1 <= m <= 500
  • 0 <= l[i] < r[i] < n
  • -10^5 <= nums[i] <= 10^5

思路:这道题很容易想到的思路就是我们对于每一个查询,对[L,R]区间内的数进行排序,然后判断每一对相邻的数的差值是不是都是一样的。这样总的复杂度为O(m*nlgn)。然而每次拷贝数据的代价是很高昂的,一个容易想到的优化思路是,如果存在两个查询之间存在包含关系或重叠部分,是可以为下一次的排序进行加速:

        包含关系:如两个查询[1,10],[3,7],我们先查询[3,7],并对[3,7]之间的数进行排序,判断差分。到下一次查询[1,10]时,我们可以通过二分查找的方式将[1,2],[8,10]这两个区间上的数以有序的方式插进[3,7]。

        重叠部分:如两个查询[3,7],[5,9],我们可以拆成[3,5],[5,9],可知这两部分都满足有序,此时可以用归并。

然而这样做编码复杂度会非常高,同时也无法加速无重叠 、无包含的查询。

我们从等差数列本身的性质入手,等差数列满足每一个相邻数对的查都是公差d。设有一个长度为n的等差数列,最大值为max_num,最小值为min_num,那么公差可以按照如下方式求解:

\tiny d=\frac{max\_num-min\_num}{n-1}

当我们有了公差之后,我们可以反推出这个数列内所有的数

\tiny a_i=a_0+(i-1)*d

因此本题的思路可以转换为,对每一个查询[L,R],算出公差d,并判断区间内每一个数是否满足下式且只出现一次(值得注意的是,如果公差为d即最大值等于最小值则一定是等差数列)。

\tiny (nums[j]-min\_num) % d==0

class Solution {
public:
    vector<bool> checkArithmeticSubarrays(vector<int>& nums, vector<int>& l, vector<int>& r) {
        int n = nums.size(), min_num[n + 5][n + 5], max_num[n + 5][n + 5], L, R, t, idx, len, d, tempIdx, diff, min_value,  max_value;
        const int maxn = 2e5 +7;
        bool existItemIdx[maxn];
        vector<bool> isArithmetic;
        for(len = 1; len <= n; ++ len){
            for(L = 0; L + len <= n; ++ L){
                if(len == 1){
                    min_num[L][L] = max_num[L][L] = nums[L];
                }else{
                    R = L + len - 1;
                    t = L + (len >> 1) -1;
                    min_num[L][R] = min(min_num[L][t], min_num[t + 1][R]);
                    max_num[L][R] = max(max_num[L][t], max_num[t + 1][R]);
                }
            }
        }
        for(idx = 0; idx < l.size(); ++ idx){
            L = l[idx];
            R = r[idx];
            min_value = min_num[L][R];
            max_value = max_num[L][R];
            if(R - L <= 1 || max_value == min_value){//长度小于等于2或者最大最小值相等即公差为0
                isArithmetic.push_back(true);
            }else{
                d = (max_value - min_value) / (R - L);
                if(d * (R - L) == max_value - min_value){
                    memset(existItemIdx, false, sizeof(existItemIdx));
                    for(tempIdx = L; tempIdx <= R; ++ tempIdx){\
                        diff = nums[tempIdx] - min_value;
                        if(diff % d != 0 || existItemIdx[diff / d]){
                            isArithmetic.push_back(false);
                            break;
                        }else{
                            existItemIdx[diff / d] = true;
                        }
                        if(tempIdx == R){
                            isArithmetic.push_back(true);
                        }
                    }
                }else{
                    isArithmetic.push_back(false);
                }
            }
        }
        return isArithmetic;
    }
};

上述使用区间dp来求取区间最大、最小值有点大材小用了,也可以用对每一个查询遍历的方式。

class Solution {
public:
    vector<bool> checkArithmeticSubarrays(vector<int>& nums, vector<int>& l, vector<int>& r) {
        int n = nums.size(), L, R, t, idx, len, d, tempIdx, diff, min_value,  max_value;
        const int maxn = 2e5 +7;
        bool existItemIdx[maxn];
        vector<bool> isArithmetic;

        for(idx = 0; idx < l.size(); ++ idx){
            L = l[idx];
            R = r[idx];

            min_value = max_value = nums[L];
            for(tempIdx = L + 1; tempIdx <= R; ++ tempIdx){
                min_value = min(min_value, nums[tempIdx]);
                max_value = max(max_value, nums[tempIdx]);
            }

            if(R - L <= 1 || max_value == min_value){//长度小于等于2或者最大最小值相等即公差为0
                isArithmetic.push_back(true);
            }else{
                d = (max_value - min_value) / (R - L);
                if(d * (R - L) == max_value - min_value){
                    memset(existItemIdx, false, sizeof(existItemIdx));
                    for(tempIdx = L; tempIdx <= R; ++ tempIdx){\
                        diff = nums[tempIdx] - min_value;
                        if(diff % d != 0 || existItemIdx[diff / d]){
                            isArithmetic.push_back(false);
                            break;
                        }else{
                            existItemIdx[diff / d] = true;
                        }
                        if(tempIdx == R){
                            isArithmetic.push_back(true);
                        }
                    }
                }else{
                    isArithmetic.push_back(false);
                }
            }
        }
        return isArithmetic;
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

(五)大数据实战——使用模板虚拟机实现hadoop集群虚拟机克隆及网络相关配置

前言 本节内容我们实现虚拟机的克隆&#xff0c;主要根据模板虚拟机克隆三台hadoop虚拟机&#xff0c;用于hadoop集群的搭建&#xff0c;同时根据上一小节的内容&#xff0c;配置hadoop虚拟机的主机名、ip网络等&#xff0c;最终完成hadoop虚拟机的实例化。 正文 虚拟机克隆…

MATLAB | 全网最详细网络图(图论图)绘制教程

一篇超超超长&#xff0c;超超超全面网络图绘制教程&#xff0c;本篇基本能讲清楚所有绘制要点&#xff0c;当然图论与网络优化的算法一篇不可能完全讲清楚&#xff0c;未来如果看的人多可以适当更新&#xff0c;同时做部分网络图绘图复刻。 以下是本篇绘图实验效果&#xff1…

Java中的String类

String类1.String类1.1 特性1.2 面试题1.3 常用方法1.4 String与其他类型之间的转换2. StringBuilder类、StringBuffer类&#xff1a;可变字符序列1.String类 1.1 特性 String类为final类&#xff0c;不可被继承&#xff0c;代表不可变的字符序列&#xff1b; 实现了Serializ…

webpack——使用、分析打包代码

世上本无nodejs js最初是在前端浏览器上运行的语言&#xff0c;js代码一旦脱离了浏览器环境&#xff0c;就无法被运行。直到nodejs的出现&#xff0c;我们在电脑上配置了node环境&#xff0c;就可以让js代码脱离浏览器&#xff0c;在node环境中运行。 浏览器不支持模块化 nodej…

STL—vector

vector介绍在C标准库中&#xff0c;vector是一个常用的序列式容器&#xff08;线性结构&#xff09;&#xff0c;它就好比c语言中的数组&#xff0c;但是vector有一些数组没有的功能&#xff0c;是一个封装好了的类。想要使用vector需要先引入头文件&#xff1a;#include<ve…

【C陷阱与缺陷】----语法陷阱

&#x1f4af;&#x1f4af;&#x1f4af; 要理解一个C程序&#xff0c;必须理解这些程序是如何组成声明&#xff0c;表达式&#xff0c;语句的。虽然现在对C的语法定义很完善&#xff0c;几乎无懈可击&#xff0c;大门有时这些定义与人们的直觉相悖&#xff0c;或容易引起混淆…

【机器学习】综述:机器学习中的模型评价、模型选择与算法选择

文章目录一、前言二、论文摘要三、简介&#xff1a;基本的模型评估项和技术3.1 性能评估&#xff1a;泛化性能 vs. 模型选择四、Bootstrapping 和不确定性五、交叉验证和超参数优化一、前言 最近在做实验的时候&#xff0c;发现树模型有过拟合的情况发生&#xff0c;为此&…

蓝桥杯每日一真题—— [蓝桥杯 2021 省 AB2] 完全平方数(数论,质因数分解)

文章目录[蓝桥杯 2021 省 AB2] 完全平方数题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1样例 #2样例输入 #2样例输出 #2提示思路&#xff1a;理论补充&#xff1a;完全平方数的一个性质&#xff1a;完全平方数的质因子的指数一定为偶数最终思路&#xff1a;小插曲&am…

直面风口,未来不仅是中文版ChatGPT,还有AGI大时代在等着我们

说到标题的AI2.0这个概念的研究早在2015年就研究起步了&#xff0c;其实大家早已知道&#xff0c;人工智能技术必然是未来科技发展战略中的重要一环&#xff0c;今天我们就从AI2.0入手&#xff0c;以GPT-4及文心一言的发布为切入角度&#xff0c;来谈一谈即将降临的AGI时代。 关…

Linux搭建GitLab私有仓库,并内网穿透实现公网访问

文章目录前言1. 下载Gitlab2. 安装Gitlab3. 启动Gitlab4. 安装cpolar5. 创建隧道配置访问地址6. 固定GitLab访问地址6.1 保留二级子域名6.2 配置二级子域名7. 测试访问二级子域名前言 GitLab 是一个用于仓库管理系统的开源项目&#xff0c;使用Git作为代码管理工具&#xff0c…

基于Springboot实现商务安全邮箱邮件收发 源码+论文展示

基于Springboot实现商务安全邮箱邮件收发 源码论文开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Ma…

【多线程】定时器和线程池

✨个人主页&#xff1a;bit me&#x1f447; ✨当前专栏&#xff1a;Java EE初阶&#x1f447; ✨每日一语&#xff1a;种一棵树最好的时间是十年前&#xff0c;其次是现在。 目 录⌚️一. 定时器&#x1f4c4;1. 定时器是什么&#x1f4c3;2. 标准库中的定时器&#x1f4d1;3.…

【C语言初阶】初识C语言 | C语言知识预览

文章目录&#x1f490;专栏导读&#x1f490;文章导读&#x1f337;什么是C语言&#xff1f;&#x1f337;第一个C语言程序&#x1f337;数据类型&#x1f337;变量、常量、字符串&#x1f33a;定义变量的方法&#x1f33a;变量的分类&#x1f33a;变量的使用&#x1f33a;变量…

DJ2-5 DNS:Internet 的目录服务

目录 1. DNS 简介 2. DNS 服务器提供的功能 3. 分布式、层次数据库 4. DNS 查询方法 5. DNS 缓存和权威 DNS 服务器记录更新 6. DNS 记录 7. DNS 报文 8. 在 DNS 数据库中插入记录 9. DNS 攻击 1. DNS 简介 名称&#xff1a;Domain Name System DNS 是&#xff1a; …

vue面试题(day06)

文章目录前言请谈谈WXML与标准的html的异同&#xff1f;请谈谈WXSS和CSS的异同&#xff1f;请谈谈微信小程序主要目录和文件的作用&#xff1f;请谈谈小程序的双向绑定和vue的异同&#xff1f;简单描述下微信小程序的相关文件类型&#xff1f;微信小程序有哪些传值(传递数据)方…

【新星计划2023】SQL SERVER (01) -- 基础知识

【新星计划2023】SQL SERVER -- 基础知识1. Introduction1.1 Official Website1.2 Conn Tool2. 基础命令2.1 建库建表2.2 Alter2.3 Drop2.3 Big Data -- Postgres3.Awakening1. Introduction 1.1 Official Website 官方文档&#xff08;小技巧&#xff09; Officail Website: …

十个Python图像处理工具,不可不知

这些Python库提供了一种简单直观的方法来转换图像并理解底层数据。 今天的世界充满了数据&#xff0c;图像是这些数据的重要组成部分。但是&#xff0c;在使用它们之前&#xff0c;必须对这些数字图像进行处理 - 分析和操作&#xff0c;以提高其质量或提取一些可以使用的信息。…

【C++学习】继承

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《C学习》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; C是面向对象的编程语言&#xff0c;它有很多的特性&#xff0c;但是最重要的就是封装&#xff0c;继承…

【3DoF算法】

VR 3DoF算法介绍 核心&#xff1a;3DoF算法应用场景&#xff0c;在VIO应用中&#xff0c;当只有测量没有观测的情况下&#xff0c;6DoF算法的预测会退化成一个只有测量的3DoF算法&#xff0c;这时候需要使用3DoF算法&#xff0c;来更加稳定准确的获取3DoF位姿&#xff0c;直到…

【VSCode】Windows 下搭建 Fortran 环境

文章目录Part.I 预备知识Part.II 安装与配置Chap.I 编译环境Chap.II 插件Part.III 测试Chap.I 一个示例Chap.II 注意事项Part.I 预备知识 Fortran 是一种比较古老的语言了&#xff0c;当时作为一种科学计算工具&#xff0c;还是比较火的&#xff0c;因为很多有名的软件都是基于…
最新文章