📌  相关文章
📜  所有可能的子数组中最大元素和第二最大元素的最大XOR值

📅  最后修改于: 2021-04-22 09:53:45             🧑  作者: Mango

给定N个不同的正整数组成的数组arr [] ,让我们分别将max(i,j)secondMax(i,j)表示为子数组arr [i…l]的最大值和第二最大值。任务是找到ij的所有可能值的max(i,j)XOR secondMax(i,j)最大值请注意,子数组的大小必须至少为两个。

例子:

天真的方法:天真的方法是简单地一个接一个地遍历所有子数组,然后找到所需的值。这种方法需要O(N 3 )时间复杂度。

有效的方法:假设arr [i]是某个子数组的第二个最大元素,则该最大元素可以是在向前或向后方向上大于arr [i]的第一个元素。
因此,可以看出,除了第一个和最后一个元素之外,每个元素最多只能充当第二个最大元素。现在,只需计算向前和向后方向上每个元素的下一个更大的元素,然后返回它们的最大XOR。本文介绍了一种使用堆栈查找下一个更大元素的方法。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
  
// Function to return the maximum possible xor
int maximumXor(int arr[], int n)
{
    stack sForward, sBackward;
  
    // To store the final answer
    int ans = -1;
  
    for (int i = 0; i < n; i++) {
  
        // Borward traversal
        while (!sForward.empty()
               && arr[i] < arr[sForward.top()]) {
            ans = max(ans, arr[i] ^ arr[sForward.top()]);
            sForward.pop();
        }
        sForward.push(i);
  
        // Backward traversal
        while (!sBackward.empty()
               && arr[n - i - 1] < arr[sBackward.top()]) {
            ans = max(ans, arr[n - i - 1] ^ arr[sBackward.top()]);
            sBackward.pop();
        }
  
        sBackward.push(n - i - 1);
    }
    return ans;
}
  
// Driver code
int main()
{
    int arr[] = { 8, 1, 2 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    cout << maximumXor(arr, n);
  
    return 0;
}


Java
// Java implementation of the approach
import java.util.*;
  
class GFG
{
  
// Function to return the maximum possible xor
static int maximumXor(int arr[], int n)
{
    Stack sForward = new Stack(),
            sBackward = new Stack();
  
    // To store the final answer
    int ans = -1;
  
    for (int i = 0; i < n; i++)
    {
  
        // Borward traversal
        while (!sForward.isEmpty()
            && arr[i] < arr[sForward.peek()]) 
        {
            ans = Math.max(ans, arr[i] ^ arr[sForward.peek()]);
            sForward.pop();
        }
        sForward.add(i);
  
        // Backward traversal
        while (!sBackward.isEmpty()
            && arr[n - i - 1] < arr[sBackward.peek()]) 
        {
            ans = Math.max(ans, arr[n - i - 1] ^ arr[sBackward.peek()]);
            sBackward.pop();
        }
  
        sBackward.add(n - i - 1);
    }
    return ans;
}
  
// Driver code
public static void main(String[] args)
{
    int arr[] = { 8, 1, 2 };
    int n = arr.length;
  
    System.out.print(maximumXor(arr, n));
  
}
}
  
// This code is contributed by 29AjayKumar


Python3
# Python3 implementation of the approach
  
# Function to return the maximum possible xor
def maximumXor(arr: list, n: int) -> int:
    sForward, sBackward = [], []
  
    # To store the final answer
    ans = -1
  
    for i in range(n):
  
        # Borward traversal
        while len(sForward) > 0 and arr[i] < arr[sForward[-1]]:
            ans = max(ans, arr[i] ^ arr[sForward[-1]])
            sForward.pop()
  
        sForward.append(i)
  
        # Backward traversal
        while len(sBackward) > 0 and arr[n - i - 1] < arr[sBackward[-1]]:
            ans = max(ans, arr[n - i - 1] ^ arr[sBackward[-1]])
            sBackward.pop()
  
        sBackward.append(n - i - 1)
  
    return ans
  
# Driver Code
if __name__ == "__main__":
  
    arr = [8, 1, 2]
    n = len(arr)
    print(maximumXor(arr, n))
  
# This code is contributed by
# sanjeev2552


C#
// C# implementation of the approach
using System;
using System.Collections.Generic;
  
class GFG
{
  
// Function to return the maximum possible xor
static int maximumXor(int []arr, int n)
{
    Stack sForward = new Stack(),
            sBackward = new Stack();
  
    // To store the readonly answer
    int ans = -1;
  
    for (int i = 0; i < n; i++)
    {
  
        // Borward traversal
        while (sForward.Count != 0
            && arr[i] < arr[sForward.Peek()]) 
        {
            ans = Math.Max(ans, arr[i] ^ arr[sForward.Peek()]);
            sForward.Pop();
        }
        sForward.Push(i);
  
        // Backward traversal
        while (sBackward.Count != 0
            && arr[n - i - 1] < arr[sBackward.Peek()]) 
        {
            ans = Math.Max(ans, arr[n - i - 1] ^ arr[sBackward.Peek()]);
            sBackward.Pop();
        }
  
        sBackward.Push(n - i - 1);
    }
    return ans;
}
  
// Driver code
public static void Main(String[] args)
{
    int []arr = { 8, 1, 2 };
    int n = arr.Length;
  
    Console.Write(maximumXor(arr, n));
  
}
}
  
// This code is contributed by PrinciRaj1992


输出:
9

时间复杂度: O(N)