Open In App

Find smallest Subarray with Maximum Xor starting from each index

Given an array A[] consisting of N elements, the task is to find the minimum length of the subarray starting from each index and the bitwise OR value is the maximum among all possible subarrays starting from that index.

Examples:



Input: A[] = [4, 5, 2, 9, 11]
Output: [4, 3, 2, 2, 1]
Explanation: For i=0, subarray [4, 5, 2, 9] is having maximum OR of 15 and a minimum size of 4
For i=1, subarray [5, 2, 9] is having maximum OR of 15 and a minimum size of 3
For i=2, subarray [2, 9] is having maximum OR of 11 and a minimum size of 2
For i=3, subarray [9, 11] is having maximum OR of 11 and a minimum size of 2
For i=4, subarray [11] is having maximum OR of 11 and a minimum size of 1

Input: A[] = [7, 5, 2, 18, 11]
Output: [5, 4, 3, 2, 1]



Naive approach: The basic way to solve the problem is as follows:

For every ith element start a loop from it to find all the subarrays  starting from that index and check for the maximum XOR and minimum size.

Follow the steps mentioned below to implement the idea:

Below is the implementation of the above approach.




// C++ code to implement the approach.
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the minimum length
// of subarrays having maximum OR
vector<int> MaxBitWiseOR_Array(vector<int>& nums)
{
    int n = nums.size();
    if (n == 1 and nums[0] == 0)
        return { 1 };
    vector<int> mor(n), ans(n);
    mor[n - 1] = nums[n - 1];
    for (int i = n - 2; i >= 0; i--)
        mor[i] = mor[i + 1] | nums[i];
    for (int i = 0; i < n; i++) {
        int j = i;
        int x = 0;
        while (j < n and x != mor[i]) {
            x |= nums[j];
            j++;
        }
        if (j < n and nums[j] == 0 and i == j)
            j++;
        ans[i] = j - i;
    }
    return ans;
}
 
// Driver code
int main()
{
    vector<int> Arr = { 4, 5, 2, 9, 11 };
 
    // Function Call
    vector<int> ans = MaxBitWiseOR_Array(Arr);
    for (int i = 0; i < ans.size(); i++)
        cout << ans[i] << " ";
 
    return 0;
}




// Java code to implement the approach.
import java.io.*;
 
class GFG {
    // Function to find the minimum length
    // of subarrays having maximum OR
    public static int[] MaxBitWiseOR_Array(int nums[])
    {
        int n = nums.length;
        if (n == 1 && nums[0] == 0) {
            int temp[] = new int[1];
            temp[0] = 1;
            return temp;
        }
        int mor[] = new int[n];
        int ans[] = new int[n];
        mor[n - 1] = nums[n - 1];
        for (int i = n - 2; i >= 0; i--)
            mor[i] = mor[i + 1] | nums[i];
        for (int i = 0; i < n; i++) {
            int j = i;
            int x = 0;
            while (j < n && x != mor[i]) {
                x |= nums[j];
                j++;
            }
            if (j < n && nums[j] == 0 && i == j)
                j++;
            ans[i] = j - i;
        }
        return ans;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int Arr[] = { 4, 5, 2, 9, 11 };
 
        // Function Call
        int ans[] = MaxBitWiseOR_Array(Arr);
        for (int i = 0; i < ans.length; i++)
            System.out.print(ans[i] + " ");
    }
}
 
// This code is contributed by Rohit Pradhan




# Python code to implement the approach.
 
# Function to find the minimum length of subarrays having maximum OR
def MaxBitWiseOR_Array(nums):
    n = len(nums)
    if(n is 1 and nums[0] is 0):
        temp = [0] * 1
        temp[0] = 1
        return temp
 
    mor = [0] * n
    ans = [0] * n
    mor[n-1] = nums[n-1]
    for i in range(n-2, -1, -1):
        mor[i] = mor[i+1] | nums[i]
 
    for i in range(n):
        j = i
        x = 0
        while(j < n and x is not mor[i]):
            x |= nums[j]
            j += 1
 
        if(j < n and nums[j] is 0 and i is j):
            j += 1
 
        ans[i] = j-i
 
    return ans
 
Arr = [4, 5, 2, 9, 11]
 
# Function call
ans = MaxBitWiseOR_Array(Arr)
for i in range(len(ans)):
    print(ans[i], end=" ")
 
# This code is contributed by lokeshmvs21.




// C# code to implement the approach.
using System;
public class GFG {
 
    // Function to find the minimum length
    // of subarrays having maximum OR
    public static int[] MaxBitWiseOR_Array(int[] nums)
    {
        int n = nums.Length;
        if (n == 1 && nums[0] == 0) {
            int[] temp = new int[1];
            temp[0] = 1;
            return temp;
        }
        int[] mor = new int[n];
        int[] ans = new int[n];
        mor[n - 1] = nums[n - 1];
        for (int i = n - 2; i >= 0; i--)
            mor[i] = mor[i + 1] | nums[i];
        for (int i = 0; i < n; i++) {
            int j = i;
            int x = 0;
            while (j < n && x != mor[i]) {
                x |= nums[j];
                j++;
            }
            if (j < n && nums[j] == 0 && i == j)
                j++;
            ans[i] = j - i;
        }
        return ans;
    }
 
    static public void Main()
    {
 
        // Code
        int[] Arr = { 4, 5, 2, 9, 11 };
 
        // Function Call
        int[] ans = MaxBitWiseOR_Array(Arr);
        for (int i = 0; i < ans.Length; i++)
            Console.Write(ans[i] + " ");
    }
}
 
// This code is contributed by lokeshmvs21.




<script>
        // JavaScript code for the above approach
 
 
 
        // Function to find the minimum length
        // of subarrays having maximum OR
        function MaxBitWiseOR_Array(nums) {
            let n = nums.length;
            if (n == 1 && nums[0] == 0)
                return [1];
            let mor = new Array(n), ans = new Array(n);
            mor[n - 1] = nums[n - 1];
            for (let i = n - 2; i >= 0; i--)
                mor[i] = mor[i + 1] | nums[i];
            for (let i = 0; i < n; i++) {
                let j = i;
                let x = 0;
                while (j < n && x != mor[i]) {
                    x |= nums[j];
                    j++;
                }
                if (j < n && nums[j] == 0 && i == j)
                    j++;
                ans[i] = j - i;
            }
            return ans;
        }
 
        // Driver code
        let Arr = [4, 5, 2, 9, 11];
 
        // Function Call
        let ans = MaxBitWiseOR_Array(Arr);
        for (let i = 0; i < ans.length; i++)
            document.write(ans[i] + " ");
 
 
 // This code is contributed by Potta Lokesh
 
    </script>

Output
4 3 2 2 1 

Time Complexity: O(N2)
Auxiliary Space: O(N)

Efficient Approach: To solve the problem follow the below steps:

We will create an array  to store the latest occurrence of a setbit of maximum possible OR for ith element in the array and the ith result will be the maximum difference of index of any setbit and current index.

Follow the below steps to implement the idea:

Below is the implementation of the above approach:




// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
 
vector<int> MaxBitWiseOR_Array(vector<int>& nums)
{
    int n = nums.size();
    vector<int> res(n, 1);
    vector<int> latest(32);
    for (int i = n - 1; i >= 0; i--) {
        for (int j = 0; j < 32; j++) {
            if (nums[i] & (1 << j))
                latest[j] = i;
            res[i] = max(res[i], latest[j] - i + 1);
        }
    }
    return res;
}
 
// Driver code
int main()
{
    vector<int> Arr = { 4, 5, 2, 9, 11 };
 
    // Function Call
    vector<int> ans = MaxBitWiseOR_Array(Arr);
    for (int i = 0; i < ans.size(); i++)
        cout << ans[i] << " ";
}




/*package whatever //do not write package name here */
import java.io.*;
import java.util.*;
class GFG {
 
  public static ArrayList<Integer>
    MaxBitWiseOR_Array(int[] nums)
  {
    int n = nums.length;
    ArrayList<Integer> res = new ArrayList<Integer>();
    for (int i = 0; i < n; i++) {
      res.add(1);
    }
    List<Integer> latest = new ArrayList<Integer>();
    for (int i = 0; i < 32; i++) {
      latest.add(0);
    }
    for (int i = n - 1; i >= 0; i--) {
      for (int j = 0; j < 32; j++) {
        if ((nums[i] & (1 << j)) != 0)
          latest.set(j, i);
        res.set(i, Math.max(res.get(i),
                            latest.get(j) - i + 1));
      }
    }
    return res;
  }
  public static void main(String[] args)
  {
    int[] Arr = { 4, 5, 2, 9, 11 };
 
    // Function Call
    ArrayList<Integer> ans = new ArrayList<Integer>();
    ans = MaxBitWiseOR_Array(Arr);
    for (int i = 0; i < ans.size(); i++)
      System.out.print(ans.get(i) + " ");
  }
}
 
// This code is contributed by akashish__




# Python code for the above approach:
def MaxBitWiseOR_Array(nums):
    n = len(nums)
    res = []
    for i in range(n):
        res.append(1)
 
    latest = []
    for i in range(32):
        latest.append(0)
 
    for i in range(n-1, -1, -1):
        for j in range(32):
            if((nums[i] & (1 << j)) != 0):
                latest[j] = i
            res[i] = max(res[i], latest[j]-i+1)
 
    return res
 
Arr = [4, 5, 2, 9, 11]
 
# Function call
ans = MaxBitWiseOR_Array(Arr)
for i in range(len(ans)):
    print(ans[i], end=" ")
 
# This code is contributed by lokeshmvs21.




// C# code to implement the approach
using System;
using System.Collections.Generic;
 
public class GFG {
 
  static int[] MaxBitWiseOR_Array(int[] nums, int n)
  {
    int[] res = new int[n];
    for (int i = 0; i < n; i++) {
      res[i] = 1;
    }
    int[] latest = new int[32];
    for (int i = n - 1; i >= 0; i--) {
      for (int j = 0; j < 32; j++) {
        if ((nums[i] & (1 << j)) != 0)
          latest[j] = i;
        res[i]
          = Math.Max(res[i], latest[j] - i + 1);
      }
    }
    return res;
  }
 
  // Driver code
  public static void Main(string[] args)
  {
    int[] Arr = { 4, 5, 2, 9, 11 };
    int N = 5;
 
    // Function Call
    int[] res = MaxBitWiseOR_Array(Arr, N);
    for (int i = 0; i < res.Length; i++)
      Console.Write(res[i] + " ");
 
    return;
  }
}
 
// This code is contributed by garg28harsh.




// JS code for the above approach:
 
function MaxBitWiseOR_Array(nums)
{
    let n = nums.length;
    let res = [];
    for(let i=0;i<n;i++)
    {
        res.push(1);
    }
    let latest = [];
    for(let i=0;i<32;i++)
    {
        latest.push(0);
    }
    for (let i = n - 1; i >= 0; i--) {
        for (let j = 0; j < 32; j++) {
            if (nums[i] & (1 << j))
                latest[j] = i;
            res[i] = Math.max(res[i], latest[j] - i + 1);
        }
    }
    return res;
}
 
// Driver code
    let Arr = [ 4, 5, 2, 9, 11 ];
 
    // Function Call
    let ans = MaxBitWiseOR_Array(Arr);
    console.log(ans);
     
    // This code is contributed by ksam24000.

Output
4 3 2 2 1 

Time Complexity: O(32 * N)
Auxiliary Space: O(32)


Article Tags :