删除操作后的最大子段和
难度:
标签:
题目描述
代码结果
运行时间: 296 ms, 内存: 38.1 MB
/*
* Solution using Java Stream API
*
* Idea: Similar to the above solution but using Java Streams for the operations
* like calculating prefix sums and finding maximums. Since Streams are not optimal
* for this type of problem, this implementation is just for demonstration.
*/
import java.util.*;
import java.util.stream.IntStream;
public class StreamSolution {
public int[] maximumSegmentSum(int[] nums, int[] removeQueries) {
int n = nums.length;
int[] answer = new int[n];
long[] prefixSum = new long[n + 1];
IntStream.range(0, n).forEach(i -> prefixSum[i + 1] = prefixSum[i] + nums[i]);
Set<Integer> removed = new HashSet<>();
long maxSum = Arrays.stream(nums).sum();
for (int i = 0; i < n; i++) {
int removeIndex = removeQueries[i];
removed.add(removeIndex);
maxSum = Long.MIN_VALUE;
int start = 0;
while (start < n) {
while (start < n && removed.contains(start)) start++;
int end = start;
while (end < n && !removed.contains(end)) end++;
long sum = IntStream.range(start, end).mapToLong(j -> nums[j]).sum();
maxSum = Math.max(maxSum, sum);
start = end;
}
answer[i] = (int) maxSum;
}
return answer;
}
}
解释
方法:
本题解采用逆向思维处理问题。初始时,所有元素都被视为删除,然后逐步添加回来,同时更新和维护子段的最大和。为了有效管理子段,使用两个数组:f记录每个子段的和,valid_range记录子段的边界。每次添加元素时,根据其左右邻居更新子段信息,合并相邻子段,并更新全局最大子段和。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
在逆向添加元素的过程中,你是如何判断一个元素是否应该与其左右邻居合并成一个子段的?
▷🦆
当合并子段时,为什么选择更新左右边界的子段和为新计算的总和,而不是只更新当前元素所在的子段?
▷🦆
逆向处理查询时,为何从数组的末尾向前处理,而不是从开始到末尾?
▷🦆
数组 `valid_range` 的具体作用是什么,它如何帮助维护和更新子段的边界信息?
▷