📜  查找满足给定条件的唯一对的数量

📅  最后修改于: 2021-06-26 21:29:52             🧑  作者: Mango

给定一个由不同的正元素组成的数组arr [] ,任务是找到唯一对(a,b)的数量,使得a是给定数组的某些子数组的最大值, b是第二个最大值。

例子:

天真的方法:我们可以找到每个子数组的对,并将它们存储在一组中,然后打印它们。该方法需要O(n 3 )时间,因为O(n 2 )用于查找子阵列, O(n)用于查找子阵列的最大和第二最大元素。

高效的方法:让我们假设a1,a2,a3,a4是数组的前四个元素,并且还假设a2a3小于a1a4大于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现场课程美国》。