1906. 查询差绝对值的最小值

🚀 用前缀和高效解决“子数组差绝对值最小值”问题


📘 一、题目描述

给定一个整数数组 nums,和一个查询数组 queries,每个查询是 [li, ri],表示一个子数组 nums[li...ri]。请你对每个查询,找出满足 nums[i] != nums[j]li ≤ i < j ≤ ri 的最小的 |nums[i] - nums[j]|

若子数组中所有元素都相等(即不存在满足条件的两数),返回 -1


✅ 例子说明:

输入:
nums = [5, 2, 3, 7, 2]
queries = [[0, 4], [1, 4], [2, 2]]

输出:
[1, 1, -1]

解释:

  • 查询 [0, 4]:子数组为 [5, 2, 3, 7, 2],不同元素中最小差值为 |2-3|=1
  • 查询 [1, 4]:子数组为 [2, 3, 7, 2],最小差值仍为 1
  • 查询 [2, 2]:子数组只有一个元素,无法构成两个不相等元素,返回 -1

🧠 二、解题思路分析

本题的难点在于如何快速回答多个区间查询,尤其是在 nums 较长、queries 较多的情况下。

观察题目条件:

  • 所有 nums[i] 的值满足 1 <= nums[i] <= 100数值范围很小
  • 这意味着我们可以使用前缀和 + 数值计数,快速判断一个数是否出现在某个区间。

💡 三、前缀和优化方案

核心思想:

我们构造一个二维数组 pre[i][x] 表示从 nums[0]nums[i-1] 中数字 x 出现的次数。

对于每个查询 [l, r]

  • 我们判断某个数字 x 是否在 nums[l...r] 中出现,只需判断:
pre[r+1][x] - pre[l][x] > 0
  • 我们只需从 1100 遍历出现的数字,记录相邻数字的最小差值。

✅ 四、Python 实现代码

class Solution:
    def minDifference(self, nums: List[int], queries: List[List[int]]) -> List[int]:
        C = 100  # 最大数字值
        n = len(nums)

        # 构建前缀频次数组 pre[i][x]: 前 i 个数中数字 x 出现的次数
        pre = [[0] * (C + 1)]
        for num in nums:
            pre.append(pre[-1][:])
            pre[-1][num] += 1

        ans = []
        for left, right in queries:
            last = 0
            best = float("inf")
            for j in range(1, C + 1):
                if pre[right + 1][j] != pre[left][j]:
                    if last != 0:
                        best = min(best, j - last)
                    last = j
            ans.append(-1 if best == float("inf") else best)

        return ans

⏱️ 五、时间与空间复杂度分析

  • 预处理时间O(n * C)C = 100
  • 每次查询时间O(C)
  • 总时间复杂度O(n * C + q * C),其中 q 是查询个数
  • 空间复杂度O(n * C) 用于前缀统计数组

这是一个时间与空间都极其可控的解决方案,非常适合面对数万级别的数据。


🧪 六、更多测试样例

nums = [1, 3, 4, 8, 6]
queries = [[0, 1], [1, 3], [0, 4], [2, 2]]

# 输出: [2, 1, 1, -1]

解释:

  • [0, 1]: [1, 3] → 差值 = 2
  • [1, 3]: [3, 4, 8] → 最小差值 = 1
  • [0, 4]: [1, 3, 4, 8, 6] → 最小差值 = 1(3 和 4)
  • [2, 2]: 单个元素 → -1

📌 七、总结与拓展

✅ 总结:

  • 充分利用了题目中“数值范围固定”的特性。
  • 使用前缀和+频次统计,实现了高效多次区间查询
  • 在大数据量场景中,优于排序法、暴力法数十倍。

📖 可拓展题型:

  • 区间中不同元素个数
  • 区间中某数字是否存在
  • 最接近目标的两个元素差值
  • 基于数值范围的小优化(桶思想)

✍️ 八、结语

这道题是“数值范围优化 + 区间统计”题目的经典例子。熟练掌握这种技巧,可以在很多类似题中灵活应对。

如果你喜欢这样的题解风格或想学习更多相关优化技巧,欢迎点赞、收藏、留言交流!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值