时间复杂度太高了,请降到log(n)*q级别
时间: 2024-09-07 22:03:20 浏览: 60
如果你希望将时间复杂度降低到对数级别 `O(log n) * q`,通常可以考虑使用二分查找(Binary Search)辅助数据结构。这里我们可以使用两个集合,一个用于存储绝对值排序后的元素(Set,保证元素唯一),另一个用于记录元素的正负及其在原数组中的位置(Map,键是元素值,值是一个列表,包含对应元素的起始和结束位置)。
以下是改进后的Java代码:
```java
import java.util.*;
class MinValue {
Map<Integer, List<int[]>> posMap; // 存储元素位置
Set<Integer> absSorted; // 存储绝对值排序后的元素
public MinValue(int[] a) {
posMap = new HashMap<>();
absSorted = new TreeSet<>(); // 树集保证查找效率
for (int i = 0; i < a.length; i++) {
absSorted.add(Math.abs(a[i])); // 添加绝对值到树集
posMap.computeIfAbsent(Math.abs(a[i]), k -> []).add(new int[]{i, i});
}
}
void updateRange(int start, int end, int x) {
if (start >= end || !absSorted.contains(Math.abs(x))) return; // 如果区间无效或x不在范围内,返回
int delta = Math.signum(x); // 判断x的正负
List<int[]> affected = posMap.getOrDefault(Math.abs(x), Collections.emptyList());
// 更新影响范围内的元素,并维护树集
for (int[] range : affected) {
int left = Math.max(start, range[0]);
int right = Math.min(end, range[1]);
range[0] += delta * (right - left);
if (!posMap.containsKey(Math.abs(range[0]))) {
posMap.put(Math.abs(range[0]), new int[][]{{range[0], range[0]}});
} else {
List<int[]> list = posMap.get(Math.abs(range[0]));
list.add(new int[]{range[0], range[0]});
Collections.sort(list, Comparator.comparingInt(a -> a[0])); // 保持有序
list = list.subList(0, list.size() - 1); // 移除最远端的元素
posMap.put(Math.abs(range[0]), list);
}
}
// 重新调整树集的顺序
for (int value : absSorted) {
if (value > Math.abs(x)) break;
List<int[]> list = posMap.get(value);
Collections.sort(list, Comparator.comparingInt(a -> a[0])); // 保持有序
posMap.put(value, list);
}
}
int getMin() {
int minAbs = absSorted.first();
if (minAbs == 0) return 0;
List<int[]> list = posMap.get(minAbs);
return list.get(0)[0] * Math.signum(minAbs);
}
public static void main(String[] args) {
int[] a = {1, -2, 3, 4, -5};
MinValue minValue = new MinValue(a);
minValue.updateRange(1, 3, 2);
System.out.println("After update: " + minValue.getMin()); // 输出:-1 (因为 [1, 3] 区间后变为 [-1, 1])
}
}
```
阅读全文