📌  相关文章
📜  删除最多一个元素后,最大化包含最大和最小数组元素的子数组计数

📅  最后修改于: 2021-10-27 03:18:40             🧑  作者: Mango

给定一个大小为N的数组arr[] 。任务是通过从数组中最多删除一个元素来最大化包含数组的最小和最大元素的子数组的计数。

例子:

朴素的方法:最简单的方法是删除每个元素,然后计算结果数组中具有最小和最大元素的子数组的数量。

时间复杂度: O(N 3 )
辅助空间: O(1)

高效方法:这种方法基于这样一种观察,即删除最大或最小元素以外的元素永远不会最大化整体结果。以下是步骤:

  1. 用 INT_MIN 初始化整体结果。
  2. 创建一个函数say proc ,它返回包含数组最小和最大元素的子数组的数量。
  3. 要计算子数组的数量,请使用两个指针方法找到子数组的开始和结束索引:
    • 用数组的最后一个元素初始化最小和最大的元素,比如lowhigh
    • 用存储lowhigh位置的数组的最后一个索引初始化两个指针p1p2
    • 现在,遍历数组并检查当前元素是否小于low ,然后更新p1
    • 如果当前元素大于high ,则更新p2
    • 在每一步,更新子数组的最大数量。
  4. 现在,计算以下三种情况下的子数组数:
    • 不删除任何元素
    • 去除最大元素后
    • 删除最小元素后。
  5. 取所有三种情况中的最大值。

下面是上述方法的实现:

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 现场工作专业课程学生竞争性编程现场课程