7022. 限制条件下元素之间的最小绝对差

超时版

cs 复制代码
public class Solution {
    public int MinAbsoluteDifference(IList<int> nums, int x) {
      if(x == 0)
      {
        return 0;
      }

      // 初始为 int 最大值
      int ans = int.MaxValue;

      // 简单直接双层遍历
      int len = nums.Count - x;
      for(int i = 0; i < len; i++)
      {
        for(int j = i + x; j < nums.Count; j++)
        {
          ans = Math.Min(ans, Math.Abs(nums[j] - nums[i]));
        }
      }
      return ans;
    }
}

超时版:

参考:借助一个有序集合保存可匹配的有序元素集合,再根据当前元素,快速找到这个元素在这个集合中的左右边界

问题:这里 查找 边界元素导致超时,需要优化

cs 复制代码
public class Solution {
    public int MinAbsoluteDifference(IList<int> nums, int x) {
      if(x == 0)
      {
        return 0;
      }

      // 初始为 int 最大值
      int ans = int.MaxValue;

      // 存储可匹配的元素,支持有序插入
      SortedSet<int> set = new SortedSet<int>();
      for(int i = x; i < nums.Count; i++)
      {
        int val = nums[i];

        // 将相隔x的元素插入
        set.Add(nums[i - x]);

        // 获取边界值
        (int low, int high) = GetBound(set, val);
        if(low != -1)
        {
          ans = Math.Min(ans, Math.Abs(val - low));
        }
        if(high != -1)
        {
          ans = Math.Min(ans, Math.Abs(val - high));
        }
      }
      return ans;
    }

    // 获取 set 中 小于等于, 大于val的元素
    public (int low, int high) GetBound(SortedSet<int> set, int val) {
      if(set.Count == 0)
      {
        return (-1, -1);
      }

      int low = -1;
      int high = -1;
      foreach(var s in set)
      {
        if(s <= val)
        {
          low = s;
          continue;
        }

        high = s;
        break;
      }
      return (low, high);
    }
}

这里使用 GetViewBetween 获取部分的节点遍历,但再最后两个测试数据中超时。

目前看,最好的办法时,可以改写SortedList,提供一个获取边界的方法,源码中其实已经包含类似的方法(FindNode),只是没有提供外界使用

cs 复制代码
public class Solution {
    public int MinAbsoluteDifference(IList<int> nums, int x) {
      if(x == 0)
      {
        return 0;
      }

      // 初始为 int 最大值
      int ans = int.MaxValue;

      // 存储可匹配的元素,支持有序插入
      SortedSet<int> set = new SortedSet<int>();
      for(int i = x; i < nums.Count; i++)
      {
        int val = nums[i];

        // 将相隔x的元素插入
        set.Add(nums[i - x]);

        // 获取边界值
        (int low, int high) = GetBound(set, val);
        if(low != -1)
        {
          ans = Math.Min(ans, Math.Abs(val - low));
        }
        if(high != -1)
        {
          ans = Math.Min(ans, Math.Abs(val - high));
        }
      }
      return ans;
    }

    // 获取 set 中 小于等于, 大于val的元素
    public (int low, int high) GetBound(SortedSet<int> set, int val) {
      if(set.Count == 0)
      {
        return (-1, -1);
      }

      int low = -1;
      int high = -1;
    
      // 数量太大时,获取部分
      if(set.Count > 1000)
      {
        set = set.GetViewBetween(val - 100000, val + 100000);
      }
      foreach(var s in set)
      {
        if(s <= val)
        {
          low = s;
          continue;
        }

        high = s;
        break;
      }
      return (low, high);
    }
}

参考版:

相关推荐
血小板要健康14 分钟前
链表 阶段算法总结
java·数据结构·笔记·算法·leetcode·链表
a1879272183122 分钟前
【算法】回溯算法(三):三记重锤与 N 皇后——记忆化、状态设计与三层漏斗
算法·leetcode·go·剪枝·回溯·n皇后·算法讲解
HugoStudio_SWAN2 小时前
洛谷 P1420 / P1179 / B4262 最长连号、数字统计与词频统计——统计的三种面孔
c++·学习·程序人生·算法
青 春 记 忆3 小时前
LeetCode 350. 两个数组的交集 II|Python 解法详解
python·算法·leetcode
阳明山水4 小时前
销量预测2025—2026:从模型竞赛到系统融合的范式转型
人工智能·深度学习·算法·机器学习·架构
桐盛科技4 小时前
拒绝“漂绿”风险:基于边缘计算的碳排放数据清洗算法与实时校验逻辑
人工智能·算法·边缘计算
wuyk5554 小时前
107.FreeRTOS 链表深度解析:从原理到面试满分答案
c语言·开发语言·数据结构·stm32·单片机·链表·面试
-dzk-4 小时前
【链表】LC 138.随机链表的复制
数据结构·链表
Tongzhi20264 小时前
通芝科技考勤软件三大发展趋势:AI大模型、无感识别与数据底座
大数据·科技·算法·爬山算法
eBest数字化转型方案5 小时前
Route Optimization for FMCG:多目标排线算法的工程实现
大数据·人工智能·算法