第一个元素最小的子数组的计数
给定一个大小为N的数组arr[] ,任务是找到第一个元素不大于子数组其他元素的子数组的数量。
例子:
Input: arr = {1, 2, 1}
Output: 5
Explanation: All subarray are: {1}, {1, 2}, {1, 2, 1}, {2}, {2, 1}, {1}
From above subarray the following meets the condition: {1}, {1, 2}, {1, 2, 1}, {2}, {1}
Input: arr[] = {1, 3, 5, 2}
Output: 8
Explanation: We have the following subarrays which meet the condition:
{1}, {1, 3}, {1, 3, 5}, {1, 3, 5, 2}, {3}, {3, 5}, {5}, {2}
天真的方法:天真的方法是运行一个嵌套循环并找到第一个元素不大于子数组中其他元素的所有子数组。
以下是上述方法的实现:
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
时间复杂度:
辅助空间: