题目地址:https://leetcode-cn.com/problems/check-if-all-1s-are-at-least-length-k-places-away/

题目描述

给你一个整数数组 nums ,和一个表示限制的整数 limit,请你返回最长连续子数组的长度,该子数组中的任意两个元素之间的绝对差必须小于或者等于 limit 。

如果不存在满足条件的子数组,则返回 0 。

示例 1:

输入:nums = [8,2,4,7], limit = 4
输出:2
解释:所有子数组如下:
[8] 最大绝对差 |8-8| = 0 <= 4.
[8,2] 最大绝对差 |8-2| = 6 > 4.
[8,2,4] 最大绝对差 |8-2| = 6 > 4.
[8,2,4,7] 最大绝对差 |8-2| = 6 > 4.
[2] 最大绝对差 |2-2| = 0 <= 4.
[2,4] 最大绝对差 |2-4| = 2 <= 4.
[2,4,7] 最大绝对差 |2-7| = 5 > 4.
[4] 最大绝对差 |4-4| = 0 <= 4.
[4,7] 最大绝对差 |4-7| = 3 <= 4.
[7] 最大绝对差 |7-7| = 0 <= 4.
因此,满足题意的最长子数组的长度为 2 。

示例 2:

输入:nums = [10,1,2,4,7,2], limit = 5
输出:4
解释:满足题意的最长子数组是 [2,4,7,2],其最大绝对差 |2-7| = 5 <= 5 。

示例 3:

输入:nums = [4,2,2,2,4,4,2,2], limit = 0
输出:3

提示:

  1. 1 <= nums.length <= 10^5
  2. 1 <= nums[i] <= 10^9
  3. 0 <= limit <= 10^9

题目大意

找出一个最长的连续子数组,这个子数组中的最大值和最小值的差 <= limit。

解题方法

滑动窗口

看了数据的范围是 10 ^ 5,我们就知道要用 O(N) 的解法,又解决的是连续数组的最大最小问题,因此最终想到滑动窗口。

滑动窗口使用两个指针:left, right,我定义的是闭区间,即判断 [left, right]区间。

窗口维护思路是:

  1. 找这个区间的最大值和最小值的差 cur = max_ - min_;
  2. 如果 cur 大于 limit,说明当前窗口已经不满足条件,必须将 left 右移;
  3. 如果 cur 小于 limit,说明满足条件,把 right 右移,尝试更大的窗口是否满足条件。

使用 res 保存最大窗口的大小,当 cur < limit 时,更新res.

整体的思路到上面就结束了。但是直接提交超时,为什么呢?因为 计算 max_ 和 min_ 直接调用库函数 max() 和 min(),这两者的时间复杂度是 O(N) 的,导致超时。

优化的重点是快速地求数组区间 max() 和 min(),即滑动窗口的最大值和最小值。可以用的方法有:

  1. C++ 使用 multiset,可以允许出现重复元素。并且自动排序。
  2. C++ 使用 map,保存出现次数,可自动排序。当一个数字的次数为0的时候,要erase掉。
  3. 使用二分维护一个排序数组。
  4. 使用两个优先级队列找最大和最小。

我用了一个简单的方法,判断区间内数字是不是都是相同的数字,如果都相同,那么不计算 max_ - min_ 了直接设置为0。就这样简单的方法就成功通过了。

Python 代码如下:

class Solution(object):
def longestSubarray(self, nums, limit):
"""
:type nums: List[int]
:type limit: int
:rtype: int
"""
N = len(nums)
left, right = 0, 0
res = 0
visited = set()
visited.add(nums[0])
while right < N:
if (len(visited) != 1):
max_ = max(nums[left : right + 1])
min_ = min(nums[left : right + 1])
cur = max_ - min_
else:
cur = 0
if cur > limit:
left += 1
else:
visited.add(nums[right])
res = max(res, right - left + 1)
right += 1
return res

欢迎关注负雪明烛的刷题博客,leetcode刷题800多,每道都讲解了详细写法!

日期

2020 年 5 月 3 日 —— 天气好热,瞬间入夏

【LeetCode】1438. 绝对差不超过限制的最长连续子数组 Longest Continuous Subarray With Absolute Diff Less Than or Equal t的更多相关文章

  1. 力扣1438. 绝对差不超过限制的最长连续子数组-C语言实现-中等难度

    题目 传送门 文本 给你一个整数数组 nums ,和一个表示限制的整数 limit,请你返回最长连续子数组的长度,该子数组中的任意两个元素之间的绝对差必须小于或者等于 limit . 如果不存在满足条 ...

  2. 1438. Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit

    Given an array of integers nums and an integer limit, return the size of the longest continuous suba ...

  3. LeetCode 674. 最长连续递增序列(Longest Continuous Increasing Subsequence) 18

    674. 最长连续递增序列 674. Longest Continuous Increasing Subsequence 题目描述 给定一个未经排序的整型数组,找到最长且连续的递增序列. Given ...

  4. LeetCode 581. Shortest Unsorted Continuous Subarray (最短无序连续子数组)

    Given an integer array, you need to find one continuous subarray that if you only sort this subarray ...

  5. [LeetCode] Shortest Unsorted Continuous Subarray 最短无序连续子数组

    Given an integer array, you need to find one continuous subarray that if you only sort this subarray ...

  6. LeetCode 209:最小长度的子数组 Minimum Size Subarray Sum

    公众号: 爱写bug(ID:icodebugs) 作者:爱写bug 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子 ...

  7. LeetCode 581. 最短无序连续子数组(Shortest Unsorted Continuous Subarray)

    581. 最短无序连续子数组 581. Shortest Unsorted Continuous Subarray 题目描述 给定一个整型数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序 ...

  8. leetcode最短无序连续子数组

    平民解法: 既然是找最小数组,那就得到一个排序好的数组,然后直接和初试数组比对,用一个left,right分别记录从最初开始不同,到最后不同的小标,最后左右做差再加一,就能得到长度. 其他解法: 双指 ...

  9. Leetcode 581.最短无序连续子数组

    最短无序连续子数组 给定一个整数数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序. 你找到的子数组应是最短的,请输出它的长度. 示例 1: 输入: [2, ...

随机推荐

  1. BZOJ 3694&&DTOJ 1972: 最短路

    题目描述 给出一个n个点m条边的无向图,n个点的编号从1~n,定义源点为1.定义最短路树如下:从源点1经过边集T到任意一点i有且仅有一条路径,且这条路径是整个图1到i的最短路径,边集T构成最短路树. ...

  2. 【k8s】使用Terraform一键部署EKS集群

    本文适用范文 使用AWS海外账号 对aws.terraform.k8s有一定的了解 新建一个独立的VPC Terraform简介 terraform是一个云端的资源编排工具,官方对自己的定位:Terr ...

  3. 【Plink】Error: Multiple instances of '_' in sample ID.?

    目录 前言 原因 解决方法 方法一:修改样本名 方法二:修改--id-delim 方法三:加入--double_id或--const-fid参数 前言 将vcf转化为plink格式时,命令如下: pl ...

  4. 解决Package is not available (for R version XXX)?

    目录 1. 更新R(不推荐) 2. 更改或指定镜像源 3.源码安装 安装R包时这个错误是经常见到的.我认为有几个方法可解决,记录之. 1. 更新R(不推荐) 简单粗暴的方法就是更新R,但这波及的范围太 ...

  5. 59. Divide Two Integers

    Divide Two Integers My Submissions QuestionEditorial Solution Total Accepted: 66073 Total Submission ...

  6. 变量、内存区域、MDK文件(map、htm)

    变量分为:局部变量和全局变量 局部变量:函数体内部定义的变量,作用域为函数内部,static声明(静态局部变量)该变量则函数调用结束后不消失而保留值,分配的存储空间不释放. 全局变量:函数体外部定义的 ...

  7. Linux-普通用户和root用户任意切换

    普通用户切换为root: 1.[xnlay@bogon ~]$含义:xnlay代表当前用户,bogon指的是主机名,~表示当前用户,$表示普通用户:[root@bogon ~]#root代表是超级用户 ...

  8. ORACLE dba_extents

    dba_extents OWNER 拥有者 SEGMENT_NAME 段名 PARTITION_NAME 分区名 SEGMENT_TYPE 段类型 TABLESPACE_NAME 表空间名 EXTEN ...

  9. 【Linux】【Basis】进程及作业管理

    进程及作业管理       内核的功用:进程管理.文件系统.网络功能.内存管理.驱动程序.安全功能       Process: 运行中的程序的一个副本:         存在生命周期       L ...

  10. Jsp/servlet分页五要素

    分页5要素: * 1)pageIndex 当前页 * 2)startIndex 从第几条数据开始 * 3)countAll 总条目数 * 4)pageSize 每页大小 * 5)pageCount 总 ...