给定一个大小为N的数组arr[] 。任务是通过从数组中最多删除一个元素来最大化包含数组的最小和最大元素的子数组的计数。
例子:
Input: arr[] = {7, 2, 5, 4, 3, 1}
Output: 4
Explanation:
Delete 1 from the array then resultant array will be {7, 2, 5, 4, 3}. So the number of subarrays which contain maximum element 7 and minimum element 2 will be 4 {[7, 2], [7, 2, 5], [7, 2, 5, 4], [7, 2, 5, 4, 3]}
Input: arr[] = {9, 9, 8, 9, 8, 9, 9, 8, 9, 8}
Output: 43
朴素的方法:最简单的方法是删除每个元素,然后计算结果数组中具有最小和最大元素的子数组的数量。
时间复杂度: O(N 3 )
辅助空间: O(1)
高效方法:这种方法基于这样一种观察,即删除最大或最小元素以外的元素永远不会最大化整体结果。以下是步骤:
- 用 INT_MIN 初始化整体结果。
- 创建一个函数say proc ,它返回包含数组最小和最大元素的子数组的数量。
- 要计算子数组的数量,请使用两个指针方法找到子数组的开始和结束索引:
- 用数组的最后一个元素初始化最小和最大的元素,比如low和high 。
- 用存储low和high位置的数组的最后一个索引初始化两个指针p1和p2 。
- 现在,遍历数组并检查当前元素是否小于low ,然后更新p1 。
- 如果当前元素大于high ,则更新p2 。
- 在每一步,更新子数组的最大数量。
- 现在,计算以下三种情况下的子数组数:
- 不删除任何元素
- 去除最大元素后
- 删除最小元素后。
- 取所有三种情况中的最大值。
下面是上述方法的实现:
Java
// Java implementation of the above approach
import java.util.*;
import java.lang.*;
class GFG {
// Function to find the maximum
// count of subarrays
static long subarray(List v)
{
int n = v.size();
if (n <= 1)
return n;
long ans = proc(v);
int low = v.get(0), pos_low = 0;
int high = v.get(0), pos_high = 0;
// Iterate the array to find
// the maximum and minimum element
for (int i = 1; i < n; i++) {
int x = v.get(i);
if (x < low) {
low = x;
pos_low = i;
}
else if (x > high) {
high = x;
pos_high = i;
}
}
// List after removing the
// minimum element
List u
= new ArrayList<>(
Collections.nCopies(n, 0));
Collections.copy(u, v);
u.remove(pos_low);
ans = Math.max(ans, proc(u));
// List after removing the
// maximum element
List w
= new ArrayList<>(
Collections.nCopies(n, 0));
Collections.copy(w, v);
w.remove(pos_high);
return Math.max(ans, proc(w));
}
// Returns the count of subarrays
// which contains both the maximum and
// minimum elements in the given list
static long proc(List v)
{
int n = v.size();
// Initialize the low and
// high of array
int low = v.get(n - 1), high = v.get(n - 1);
int p1 = n, p2 = n;
long ans = 0;
for (int i = n - 1; i >= 0; i--) {
int x = v.get(i);
// If current element is
// less than least element
if (x < low) {
low = x;
ans = 0;
}
// If current element is
// more than highest element
else if (x > high) {
high = x;
ans = 0;
}
// If current element is
// equal to low or high
// then update the pointers
if (x == low)
p1 = i;
if (x == high)
p2 = i;
// Update number of subarrays
ans += n - Math.max(p1, p2);
}
// Return the result
return ans;
}
// Driver Code
public static void main(String[] args)
{
// Given array
List arr = Arrays.asList(7, 2, 5, 4, 3, 1);
// Function Call
System.out.println(subarray(arr));
}
}
输出
4
时间复杂度: O(N)
辅助空间:O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。