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);
    }
}

参考版:

相关推荐
C#Thread24 分钟前
机器视觉--Halcon的数据结构(数组)
算法
垠二2 小时前
L2-4 寻宝图
数据结构·算法
a_j584 小时前
算法与数据结构(环形链表)
数据结构·链表
东方芷兰4 小时前
算法笔记 04 —— 算法初步(下)
c++·笔记·算法
JNU freshman5 小时前
图论 之 迪斯科特拉算法求解最短路径
算法·图论
青松@FasterAI5 小时前
【NLP算法面经】本科双非,头条+腾讯 NLP 详细面经(★附面题整理★)
人工智能·算法·自然语言处理
旅僧5 小时前
代码随想录-- 第一天图论 --- 岛屿的数量
算法·深度优先·图论
Emplace5 小时前
ABC381E题解
c++·算法
tekin5 小时前
Python 高级数据结构操作全解析:从理论到实践
数据结构·python·集合set·高级数据结构·集合操作·队列操作·堆操作
若兰幽竹6 小时前
【机器学习】衡量线性回归算法最好的指标:R Squared
算法·机器学习·线性回归