给定一个由不同的正元素组成的数组arr [] ,任务是找到唯一对(a,b)的数量,使得a是给定数组的某些子数组的最大值, b是第二个最大值。
例子:
Input: arr[] = {1, 2, 3}
Output: 2
{1, 2}, {2, 3}, {1, 2, 3} are the subarrays and the pairs
satisfying given conditions are (2, 1) and (3, 2) only.
Input: arr[] = {4, 1, 2}
Output: 3
天真的方法:我们可以找到每个子数组的对,并将它们存储在一组中,然后打印它们。该方法需要O(n 3 )时间,因为O(n 2 )用于查找子阵列, O(n)用于查找子阵列的最大和第二最大元素。
高效的方法:让我们假设a1,a2,a3,a4是数组的前四个元素,并且还假设a2和a3小于a1且a4大于a1 。
显然, (a4,a1)是必需的对之一。现在可以证明a4之后的任何元素都不能与a1配对。
由于所有的元素是唯一的,或者将有超过A4的元素大于或A4之后的所有元素将是小于A4。假设aM大于a4 。然后,从第一个元素到第M个元素的子数组将aM作为最大元素,将a4作为第二个最大元素,因此(aM,a4)将是必需的对。现在,如果直到M的所有元素都小于a4,则a4将是最大元素。无论如何, a1将仅与a4配对。
简而言之,如果存在一个大于该元素并且具有更高索引的元素,则该元素将对成对。如果数组以相反的方向遍历,则可以使用相同的参数。
因此,对的总数=前向遍历中具有较大元素的元素数+后向遍历中具有较大元素的元素数,可以使用本文中讨论的方法轻松计算。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to return the count
// of the required pairs
int countPairs(int arr[], int n)
{
// Calculating the valid pairs
// in forward direction
int forward[n] = { 0 };
stack sForward;
for (int i = 0; i < n; i++) {
while (!sForward.empty()
&& arr[i] > arr[sForward.top()]) {
forward[sForward.top()] = 1;
sForward.pop();
}
sForward.push(i);
}
// Calculating the valid pairs
// in backward direction
int backward[n] = { 0 };
stack sBackward;
for (int i = n - 1; i >= 0; i--) {
while (!sBackward.empty()
&& arr[i] > arr[sBackward.top()]) {
backward[sBackward.top()] = 1;
sBackward.pop();
}
sBackward.push(i);
}
// Calculating the total number of pairs
int res = 0;
for (int i = 0; i < n; i++) {
res += forward[i] + backward[i];
}
return res;
}
// Driver code
int main()
{
int arr[] = { 1, 2, 3, 4, 5 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << countPairs(arr, n);
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG
{
// Function to return the count
// of the required pairs
static int countPairs(int arr[], int n)
{
// Calculating the valid pairs
// in forward direction
int forward[] = new int[n];
Stack sForward = new Stack();
for (int i = 0; i < n; i++)
{
while (!sForward.empty()
&& arr[i] > arr[(Integer)sForward.peek()])
{
forward[(Integer)sForward.peek()] = 1;
sForward.pop();
}
sForward.push(i);
}
// Calculating the valid pairs
// in backward direction
int backward [] = new int[n] ;
Stack sBackward = new Stack() ;
for (int i = n - 1; i >= 0; i--)
{
while (!sBackward.empty()
&& arr[i] > arr[(Integer)sBackward.peek()])
{
backward[(Integer)sBackward.peek()] = 1;
sBackward.pop();
}
sBackward.push(i);
}
// Calculating the total number of pairs
int res = 0;
for (int i = 0; i < n; i++)
{
res += forward[i] + backward[i];
}
return res;
}
// Driver code
public static void main (String[] args)
{
int arr[] = { 1, 2, 3, 4, 5 };
int n = arr.length;
System.out.println(countPairs(arr, n));
}
}
// This code is contributed by AnkitRai01
Python3
# Python3 implementation of the approach
# Function to return the count
# of the required pairs
def countPairs(arr, n) :
# Calculating the valid pairs
# in forward direction
forward = [0] * n;
sForward = [];
for i in range(n) :
while (len(sForward) != 0 and arr[i] > arr[sForward[-1]]) :
forward[sForward[-1]] = 1;
sForward.pop();
sForward.append(i);
# Calculating the valid pairs
# in backward direction
backward = [0] * n;
sBackward = [];
for i in range(n - 1, -1, -1) :
while (len(sBackward) != 0 and arr[i] > arr[sBackward[-1]]) :
backward[sBackward[-1]] = 1;
sBackward.pop();
sBackward.append(i);
# Calculating the total number of pairs
res = 0;
for i in range(n) :
res += forward[i] + backward[i];
return res;
# Driver code
if __name__ == "__main__" :
arr = [ 1, 2, 3, 4, 5 ];
n = len(arr);
print(countPairs(arr, n));
# This code is contributed by AnkitRai01
C#
// C# implementation of the approach
using System;
using System.Collections;
class GFG
{
// Function to return the count
// of the required pairs
static int countPairs(int []arr, int n)
{
// Calculating the valid pairs
// in forward direction
int []forward = new int[n];
Stack sForward = new Stack();
for (int i = 0; i < n; i++)
{
while (sForward.Count != 0
&& arr[i] > arr[(int)sForward.Peek()])
{
forward[(int)sForward.Peek()] = 1;
sForward.Pop();
}
sForward.Push(i);
}
// Calculating the valid pairs
// in backward direction
int []backward = new int[n] ;
Stack sBackward = new Stack() ;
for (int i = n - 1; i >= 0; i--)
{
while (sBackward.Count != 0
&& arr[i] > arr[(int)sBackward.Peek()])
{
backward[(int)sBackward.Peek()] = 1;
sBackward.Pop();
}
sBackward.Push(i);
}
// Calculating the total number of pairs
int res = 0;
for (int i = 0; i < n; i++)
{
res += forward[i] + backward[i];
}
return res;
}
// Driver code
public static void Main()
{
int []arr = { 1, 2, 3, 4, 5 };
int n = arr.Length;
Console.WriteLine(countPairs(arr, n));
}
}
// This code is contributed by AnkitRai01
4
时间复杂度: O(N)
如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。