📌  相关文章
📜  第一个元素最小的子数组的计数

📅  最后修改于: 2022-05-13 01:56:15.388000             🧑  作者: Mango

第一个元素最小的子数组的计数

给定一个大小为N的数组arr[] ,任务是找到第一个元素不大于子数组其他元素的子数组的数量。

例子:

天真的方法:天真的方法是运行一个嵌套循环并找到第一个元素不大于子数组中其他元素的所有子数组。

以下是上述方法的实现:

C++
// C++ code to implement the approach
 
#include 
using namespace std;
 
// Function to find all subarrays with first
// element not bigger than other elements
int countSubarrays(vector& arr)
{
    int n = arr.size();
 
    // Cnt is initialised to n because
    // atleast n subarrays will be there
    // which is single element itself
    int cnt = n;
 
    // Two loops to find the
    // ending of each subarrays
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
 
            // Minimum element from
            // [start+1, end] of each subarray
            int mini_ele = *min_element(begin(arr) + i + 1,
                                        begin(arr) + j + 1);
 
            // Checking if minimum of
            // elements from [start+1, end] is
            // not smaller than start element
            // updating the count of subarrays
            if (mini_ele >= arr[i])
                cnt++;
        }
    }
    return cnt;
}
 
// Driver Code
int main()
{
    vector arr = { 1, 3, 5, 2 };
 
    // Function call
    cout << countSubarrays(arr) << "\n";
    return 0;
}


C++
// C++ code to implement the approach
 
#include 
using namespace std;
 
// Function to find all subarrays with first
// element not bigger than other elements
int countSubarrays(vector& arr)
{
    // Taking stack for find next smaller
    // element to the right
    stack s;
    int ans = 0;
    int n = arr.size();
 
    // Looping from right side because we next
    // smallest to the right
    for (int i = n - 1; i >= 0; i--) {
        while (!s.empty() and arr[s.top()] >= arr[i])
            s.pop();
        // The index of next smaller element
        // starting from i'th index
        int last = (s.empty() ? n : s.top());
 
        // Adding the number of subarray which
        // can be formed in the range [i, last]
        ans += (last - i);
        s.push(i);
    }
    return ans;
}
 
// Driver Code
int main()
{
    vector arr = { 1, 3, 5, 2 };
 
    // Function call
    cout << countSubarrays(arr) << "\n";
    return 0;
}


Java
// JAVA code to implement the approach
import java.util.*;
class GFG {
 
  // Function to find all subarrays with first
  // element not bigger than other elements
  public static int countSubarrays(int arr[])
  {
 
    // Taking stack for find next smaller
    // element to the right
    Stack s = new Stack();
    int ans = 0;
    int n = arr.length;
 
    // Looping from right side because we next
    // smallest to the right
    for (int i = n - 1; i >= 0; i--) {
      while (s.empty() == false
             && arr[s.peek()] >= arr[i])
        s.pop();
      // The index of next smaller element
      // starting from i'th index
      int last = ((s.empty() == true) ? n : s.peek());
 
      // Adding the number of subarray which
      // can be formed in the range [i, last]
      ans += (last - i);
      s.push(i);
    }
    return ans;
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    int arr[] = new int[] { 1, 3, 5, 2 };
 
    // Function call
    System.out.println(countSubarrays(arr));
  }
}
 
// This code is contributed by Taranpreet


Javascript



输出
8

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

有效方法:有效方法基于在元素右侧找到下一个较小元素的概念。使用这个概念来实现。请按照以下步骤操作:

  • 我们使用单调堆栈来获取右边每个元素的下一个较小的索引 因为我们想要第一个元素作为最小元素的子数组。
  • i作为起始索引的[i, j]范围内的子数组的总数为(j – i)。
  • 为每个索引i计算下一个较小的索引,为每个索引添加(ji)并不断更新有效子数组的总数。

下面是上述方法的实现。

C++

// C++ code to implement the approach
 
#include 
using namespace std;
 
// Function to find all subarrays with first
// element not bigger than other elements
int countSubarrays(vector& arr)
{
    // Taking stack for find next smaller
    // element to the right
    stack s;
    int ans = 0;
    int n = arr.size();
 
    // Looping from right side because we next
    // smallest to the right
    for (int i = n - 1; i >= 0; i--) {
        while (!s.empty() and arr[s.top()] >= arr[i])
            s.pop();
        // The index of next smaller element
        // starting from i'th index
        int last = (s.empty() ? n : s.top());
 
        // Adding the number of subarray which
        // can be formed in the range [i, last]
        ans += (last - i);
        s.push(i);
    }
    return ans;
}
 
// Driver Code
int main()
{
    vector arr = { 1, 3, 5, 2 };
 
    // Function call
    cout << countSubarrays(arr) << "\n";
    return 0;
}

Java

// JAVA code to implement the approach
import java.util.*;
class GFG {
 
  // Function to find all subarrays with first
  // element not bigger than other elements
  public static int countSubarrays(int arr[])
  {
 
    // Taking stack for find next smaller
    // element to the right
    Stack s = new Stack();
    int ans = 0;
    int n = arr.length;
 
    // Looping from right side because we next
    // smallest to the right
    for (int i = n - 1; i >= 0; i--) {
      while (s.empty() == false
             && arr[s.peek()] >= arr[i])
        s.pop();
      // The index of next smaller element
      // starting from i'th index
      int last = ((s.empty() == true) ? n : s.peek());
 
      // Adding the number of subarray which
      // can be formed in the range [i, last]
      ans += (last - i);
      s.push(i);
    }
    return ans;
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    int arr[] = new int[] { 1, 3, 5, 2 };
 
    // Function call
    System.out.println(countSubarrays(arr));
  }
}
 
// This code is contributed by Taranpreet

Javascript



输出
8

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