Given an array arr[] of size n. The task is to count the number of possible sub-arrays such that their elements can be re-arranged to form a palindrome.
Examples:
Input: arr[] = {1, 2, 1, 2}
Output: 7
{1}, {2}, {1}, {2}, {1, 2, 1}, {2, 1, 2} and {1, 2, 1, 2} are the valid sub-arrays.
Input: arr[] = {1, 2, 3, 1, 2, 3, 4}
Output: 11
Approach: There are a few observations:
- To create an even length palindrome all the distinct numbers need to have even occurrences.
- To create an odd length palindrome there has to be only one number of odd occurrences.
Now, the tricky part is to determine whether a particular section of the array can be made into a palindrome in O(1) complexity. We can use XOR to achieve this:
- For each number m, we can use it in the xor calculation as 2^n so that it contains a single set bit.
- If the xor of all the elements of a section is 0 then it means that occurrences of all the distinct numbers of this section are even.
- If the xor of all the elements of a section is greater than 0 then it means that:
- Either there is more than one distinct number with odd occurrences in which case the section cannot be re-arranged to form a palindrome
- Or exactly one number with odd occurrence (the binary representation of the number will have only 1 set bit).
Below is the implementation of the above approach:
C++
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std; typedef signed long long ll; // Function that returns true if n is a // power of 2 i.e. n has only 1 set bit bool is_power_of_two(ll n) { return !(n & (n - 1LL)); } // Function to return the count // of all valid sub-arrays int countSubArrays( int arr[], int n) { // To store the count of valid sub-arrays int cnt = 0; for ( int j = 0; j < n; j++) { ll xorval = 0LL; for ( int k = j; k < n; k++) { // num = 2 ^ arr[k] ll num = 1LL << arr[k]; xorval ^= num; // If frequency of all the elements of the // sub-array is even or there is only a // single element with odd frequency if (xorval == 0LL || is_power_of_two(xorval)) cnt++; } } // Return the required count return cnt; } // Driver code int main() { int arr[] = { 1, 2, 3, 1, 2, 3, 4 }; int n = sizeof (arr) / sizeof (arr[0]); cout << countSubArrays(arr, n); return 0; } |
Java
// Java implementation of the approach class GfG { static long ll; // Function that returns true if n is a // power of 2 i.e. n has only 1 set bit static boolean is_power_of_two( long n) { return n!= 0 && (n & (n - 1 ))== 0 ; } // Function to return the count // of all valid sub-arrays static int countSubArrays( int arr[], int n) { // To store the count of valid sub-arrays int cnt = 0 ; for ( int j = 0 ; j < n; j++) { long xorval = 0 ; for ( int k = j; k < n; k++) { // num = 2 ^ arr[k] long num = 1 << arr[k]; xorval ^= num; // If frequency of all the elements of the // sub-array is even or there is only a // single element with odd frequency if (xorval == 0 || is_power_of_two(xorval)) cnt++; } } // Return the required count return cnt; } // Driver code public static void main(String[] args) { int arr[] = { 1 , 2 , 3 , 1 , 2 , 3 , 4 }; int n = arr.length; System.out.println(countSubArrays(arr, n)); } } // This code is contributed by Prerna Saini |
Python3
# Python3 implementation of the approach # Function that returns true if n is a # power of 2 i.e. n has only 1 set bit def is_power_of_two(n): return 0 if (n & (n - 1 )) else 1 ; # Function to return the count # of all valid sub-arrays def countSubArrays(arr, n): # To store the count of valid sub-arrays cnt = 0 ; for j in range (n): xorval = 0 ; for k in range (j, n): # num = 2 ^ arr[k] num = 1 << arr[k]; xorval ^ = num; # If frequency of all the elements of the # sub-array is even or there is only a # single element with odd frequency if (xorval = = 0 or is_power_of_two(xorval)): cnt + = 1 ; # Return the required count return cnt; # Driver code arr = [ 1 , 2 , 3 , 1 , 2 , 3 , 4 ]; n = len (arr); print (countSubArrays(arr, n)); # This code is contributed by mits |
C#
// C# implementation of the approach using System; class GfG { static long ll; // Function that returns true if n is a // power of 2 i.e. n has only 1 set bit static bool is_power_of_two( long n) { //return !(n & (n - 1)); return false ; } // Function to return the count // of all valid sub-arrays static int countSubArrays( int []arr, int n) { // To store the count of valid sub-arrays int cnt = 0; for ( int j = 0; j < n; j++) { long xorval = 0; for ( int k = j; k < n; k++) { // num = 2 ^ arr[k] long num = 1 << arr[k]; xorval ^= num; // If frequency of all the elements of the // sub-array is even or there is only a // single element with odd frequency if (xorval == 0 || is_power_of_two(xorval)) cnt++; } } // Return the required count return cnt; } // Driver code public static void Main(String[] args) { int []arr = { 1, 2, 3, 1, 2, 3, 4 }; int n = arr.Length; Console.WriteLine(countSubArrays(arr, n) + "1" ); } } // This code contributed by Rajput-Ji |
PHP
<?php // PHP implementation of the approach // Function that returns true if n is a // power of 2 i.e. n has only 1 set bit function is_power_of_two( $n ) { return !( $n & ( $n - 1)); } // Function to return the count // of all valid sub-arrays function countSubArrays( $arr , $n ) { // To store the count of valid sub-arrays $cnt = 0; for ( $j = 0; $j < $n ; $j ++) { $xorval = 0; for ( $k = $j ; $k < $n ; $k ++) { // num = 2 ^ arr[k] $num = 1 << $arr [ $k ]; $xorval ^= $num ; // If frequency of all the elements of the // sub-array is even or there is only a // single element with odd frequency if ( $xorval == 0 || is_power_of_two( $xorval )) $cnt ++; } } // Return the required count return $cnt ; } // Driver code $arr = array ( 1, 2, 3, 1, 2, 3, 4 ); $n = count ( $arr ); echo countSubArrays( $arr , $n ); // This code is contributed by mits ?> |
Javascript
<script> // Javascript implementation of the approach // Function that returns true if n is a // power of 2 i.e. n has only 1 set bit function is_power_of_two(n) { return !(n & (n - 1)); } // Function to return the count // of all valid sub-arrays function countSubArrays(arr, n) { // To store the count of valid sub-arrays let cnt = 0; for (let j = 0; j < n; j++) { let xorval = 0; for (let k = j; k < n; k++) { // num = 2 ^ arr[k] let num = 1 << arr[k]; xorval ^= num; // If frequency of all the elements of the // sub-array is even or there is only a // single element with odd frequency if (xorval == 0 || is_power_of_two(xorval)) cnt++; } } // Return the required count return cnt; } // Driver code let arr = [ 1, 2, 3, 1, 2, 3, 4 ]; let n = arr.length; document.write(countSubArrays(arr, n)); </script> |
11
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!