Open In App

Find smallest Subarray with Maximum Xor starting from each index

Improve
Improve
Like Article
Like
Save
Share
Report

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:

  • Start iterating from i = 0 to N-1:
    • For each index start a nested loop from j = i to N-1:
      • Calculate the bitwise XOR if the subarray [i, j] and update the maximum XOR and minimum size accordingly.
    • Store the minimum size in an array.
  • Return the array as the required answer.

Below is the implementation of the above approach.

C++




// 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




// 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


Python3




# 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#




// 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.


Javascript




<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:

  • Traverse from i = N-1 to 0:
    • For each array traverse all the bits from j = 0 to 32:
      • If jth bit was set previously and also set in current element, update the latest occurrence of jth bit.
      • If jth bit was set previously but not in current element, then also jth bit will be set in answer.
      • Update the maximum length as the maximum among max length and the difference between the index of jth set bit and i.
      • If jth bit was not set previously, set the jth bit and update its latest occurrence.
    • The maximum length calculated in this way will be the answer for ith index. Store it in an array.
  • Return the array as the required answer.

Below is the implementation of the above approach:

C++




// 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] << " ";
}


Java




/*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__


Python3




# 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#




// 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.


Javascript




// 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)



Last Updated : 19 Dec, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads