5402. 绝对差不超过限制的最长连续子数组

本文介绍了一个算法问题,即如何找到一个整数数组中,最长的连续子数组,其中任意两个元素的绝对差小于或等于给定的限制。通过示例详细解释了问题的解决方法,包括如何维护子数组的最大最小值来判断是否满足条件。

https://leetcode-cn.com/problems/longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit

给你一个整数数组 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 <= nums.length <= 10^5
1 <= nums[i] <= 10^9
0 <= limit <= 10^9

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:维护位置i,j内的最大最小值

class Solution(object):
    def longestSubarray(self, nums, limit):
        """
        :type nums: List[int]
        :type limit: int
        :rtype: int
        """
        if len(nums) == 1:
            return 1
        # 之前一直超时,看他人题解,加这一判断后AC
        if max(nums) == min(nums):
            return len(nums)

        i, j, longnum = 0, 1, 0
        while(True):
            minnum = min(nums[i:j+1])
            maxnum = max(nums[i:j+1])
            if maxnum - minnum > limit and i < j:
                i += 1
            elif maxnum - minnum <= limit and j < len(nums) - 1:
                longnum = max(longnum, j-i+1)
                j += 1
            else:
                break
        longnum = max(longnum, j-i+1)
        return longnum

 

定义任意数组 b b 的得分为 b b 的度减去 b b 中同元素的数量。例如: [ 1 , 2 , 2 , 4 ] [1,2,2,4] 的得分为 1 1,因为它的度为 4 4,且只有 3 3 个同元素( 1 1、 2 2、 4 4)。 [ 1 , 1 , 1 ] [1,1,1] 的得分为 2 2,因为它的度为 3 3,且只有 1 1 个同元素( 1 1)。 空数组的得分为 0 0。 你有一个数组 a a。你需要从 a a 中删除一些 非空 连续子数组 最多 一次。 更正式地,你可以做以下操作 最多 一次: 选择两个整数 l l、 r r,其中 1 ≤ l ≤ r ≤ n 1≤l≤r≤n,并 从 a a 中删除连续子数组 [ a l , … , a r ] [a l ​ ,…,a r ​ ](即,用 [ a 1 , … , a l − 1 , a r + 1 , … , a n ] [a 1 ​ ,…,a l−1 ​ ,a r+1 ​ ,…,a n ​ ] 替换 a a)。 输出一个操作,使得 a a 的得分 最大;如果有多个答案,输出一个 最小化 操作后 a a 的最终度的答案。如果仍然有多个答案,你可以输出其中任何一个。 输入 第一行包含一个整数 t t ( 1 ≤ t ≤ 10 4 1≤t≤10 4 ) — 测试用例的数量。 每个测试用例的第一行包含一个整数 n n ( 1 ≤ n ≤ 2 ⋅ 10 5 1≤n≤2⋅10 5 ) — 数组 a a 的度。 每个测试用例的第二行包含 n n 个整数 a 1 , a 2 , … , a n a 1 ​ ,a 2 ​ ,…,a n ​ ( 1 ≤ a i ≤ n 1≤a i ​ ≤n)。 所有测试用例中 n n 的总超过 2 ⋅ 10 5 2⋅10 5 。 输出 对于每个测试用例,如果你想进行任何操作,输出 0 0。 否则,输出两个整数 l l r r ( 1 ≤ l ≤ r ≤ n 1≤l≤r≤n),表示被删除子数组的左边界右边界。 被删除的子数组应选择使得得分最大,并在所有这样的答案中选择任何一个使得数组的最终度最小化的答案。 示例 Inputcopy Outputcopy 3 1 1 5 1 1 1 1 1 4 2 1 3 2 1 1 0 2 3 注意 在第一个测试用例中,我们有两个选项: 什么都做: [ 1 ] [1] 的得分为 1 − 1 = 0 1−1=0。 删除包含 l = 1 l=1、 r = 1 r=1 的子数组:我们删除唯一的元素,得到一个得分为 0 0 的空数组。 因此,可能的最大得分为 0 0。然而,由于我们需要额外最小化数组的最终度,我们 必须 输出第二个选项 l = r = 1 l=r=1。注意,什么都做的第一个选项是 正确 的,因为它的最终度更。 在第二个测试用例中,没有选择任何子数组,因此 a a 仍然是 [ 1 , 1 , 1 , 1 , 1 ] [1,1,1,1,1]。这的度为 5 5,有 1 1 个同元素,因此得分为 5 − 1 = 4 5−1=4。这可以证明是一个最大化得分的最短数组。 在第三个测试用例中,选择的子数组是 [ 2 , 1 , 3 , 2 ] [2,1,3,2],之后 a a 变为 [ 2 , 2 ] [2,2]。这的度为 2 2,有 1 1 个同元素,因此得分为 2 − 1 = 1 2−1=1。这可以证明是一个最大化得分的最短数组。 用c++
最新发布
12-31
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值