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