classSolution: defminAbsoluteDifference(self, nums: List[int], x: int) -> int: ans = inf sl = SortedList((-inf, inf)) # 哨兵 for v, y inzip(nums, nums[x:]): sl.add(v) j = sl.bisect_left(y) ans = min(ans, sl[j] - y, y - sl[j - 1]) return ans
[sol-Java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classSolution { publicintminAbsoluteDifference(List<Integer> nums, int x) { vara= nums.stream().mapToInt(i -> i).toArray(); intans= Integer.MAX_VALUE, n = a.length; vars=newTreeSet<Integer>(); s.add(Integer.MAX_VALUE); // 哨兵 s.add(Integer.MIN_VALUE / 2); for (inti= x; i < n; i++) { s.add(a[i - x]); inty= a[i]; ans = Math.min(ans, Math.min(s.ceiling(y) - y, y - s.floor(y))); } return ans; } }
[sol-C++]
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution { public: intminAbsoluteDifference(vector<int> &nums, int x){ int ans = INT_MAX, n = nums.size(); set<int> s = {INT_MIN / 2, INT_MAX}; // 哨兵 for (int i = x; i < n; i++) { s.insert(nums[i - x]); int y = nums[i]; auto it = s.lower_bound(y); // 注意用 set 自带的 lower_bound,具体见视频中的解析 ans = min(ans, min(*it - y, y - *prev(it))); // 注意不能写 *--it,这是未定义行为:万一先执行了 --it,前面的 *it-y 就错了 } return ans; } };
[sol-Go]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// import "github.com/emirpasic/gods/trees/redblacktree" funcminAbsoluteDifference(nums []int, k int)int { ans := math.MaxInt t := redblacktree.NewWithIntComparator() t.Put(math.MaxInt, nil) // 哨兵 t.Put(math.MinInt/2, nil) for i, y := range nums[k:] { t.Put(nums[i], nil) c, _ := t.Ceiling(y) f, _ := t.Floor(y) ans = min(ans, min(c.Key.(int)-y, y-f.Key.(int))) } return ans }
funcmin(a, b int)int { if b < a { return b }; return a }
复杂度分析
时间复杂度:\mathcal{O}((n-x)\log (n-x)),其中 n 为 nums 的长度。