Find minimum elements after considering all possible transformations
Given an array of three colors. The array elements have a special property. Whenever two elements of different colors become adjacent to each other, they merge into an element of the third color. How many minimum numbers of elements can be there in the array after considering all possible transformations.
Example:
Input : arr[] = {R, G}
Output : 1
G B -> {G B} R -> R
Input : arr[] = {R, G, B}
Output : 2
Explanation :
R G B -> [R G] B -> B B
OR
R G B -> R {G B} -> R R
Scenarios
Before you rush into solution, we would suggest you try out different examples and see if you can find any pattern.
Let us see few more scenarios:
1. R R R, Output 3
2. R R G B -> R [R G] B -> [R B] B -> [G B] -> R, Output 1
3. R G R G -> [R G] R G -> [B R] G ->G G, Output 2
4. R G B B G R -> R [G B] B G R ->R [R B] G R ->[R G] G R
-> [B G] R ->R R, Output 2
5. R R B B G -> R [R B] [B G] -> R [G R] -> [R B] -> G,
Output 1
Did you find any pattern in output?
Possible Patterns
Let n be number of elements in array. No matter what the input is, we always end up in three types of outputs:
- n: When no transformation can take place at all
- 2: When number of elements of each color are all odd or all even
- 1: When number of elements of each color are mix of odd and even
Steps:
1) Count the number of elements of each color.
2) Then only one out of the following four cases can happen:
......1) There are elements of only one color, return n.
......2) There are even number of elements of each color, return 2.
......3) There are odd number of elements of each color, return 2.
......4) In every other case, return 1.
(The elements will combine with each other repeatedly until
only one of them is left)
Below is the implementation of the above algorithm.
C++
#include <iostream>
using namespace std;
int findMin( char arr[], int n)
{
int b_count = 0, g_count = 0, r_count = 0;
for ( int i = 0; i < n; i++)
{
if (arr[i] == 'B' ) b_count++;
if (arr[i] == 'G' ) g_count++;
if (arr[i] == 'R' ) r_count++;
}
if (b_count==n || g_count==n || r_count==n)
return n;
if ((r_count&1 && g_count&1 && b_count&1) )
return 2;
if (!(r_count & 1) && !(g_count & 1) &&
!(b_count & 1) )
return 2;
return 1;
}
int main()
{
char arr[] = { 'R' , 'G' , 'B' , 'R' };
int n = sizeof (arr)/ sizeof (arr[0]);
cout << findMin(arr, n);
return 0;
}
|
Java
import java.util.*;
class solution
{
static int findMin( char arr[], int n)
{
int b_count = 0 , g_count = 0 , r_count = 0 ;
for ( int i = 0 ; i < n; i++)
{
if (arr[i] == 'B' ) b_count++;
if (arr[i] == 'G' ) g_count++;
if (arr[i] == 'R' ) r_count++;
}
if (b_count==n || g_count==n || r_count==n)
return n;
if ((r_count& 1 ) == 1 ) {
if ((g_count& 1 ) == 1 ) {
if ((b_count& 1 ) == 1 )
return 2 ;
}
}
if ((r_count & 1 ) == 0 )
{
if ((g_count & 1 ) == 0 )
{
if ((b_count & 1 ) == 0 )
return 2 ;
}
}
return 1 ;
}
public static void main(String args[])
{
char arr[] = { 'R' , 'G' , 'B' , 'R' };
int n = arr.length;
System.out.println(findMin(arr, n));
}
}
|
Python 3
def findMin(arr, n):
b_count = 0
g_count = 0
r_count = 0
for i in range (n):
if (arr[i] = = 'B' ):
b_count + = 1
if (arr[i] = = 'G' ):
g_count + = 1
if (arr[i] = = 'R' ):
r_count + = 1
if (b_count = = n or
g_count = = n or r_count = = n):
return n
if ((r_count& 1 and
g_count& 1 and b_count& 1 )):
return 2
if ( not (r_count & 1 ) and not
(g_count & 1 ) and not (b_count & 1 )):
return 2
return 1
if __name__ = = "__main__" :
arr = [ 'R' , 'G' , 'B' , 'R' ]
n = len (arr)
print (findMin(arr, n))
|
C#
using System;
class GFG
{
static int findMin( char []arr, int n)
{
int b_count = 0, g_count = 0, r_count = 0;
for ( int i = 0; i < n; i++)
{
if (arr[i] == 'B' ) b_count++;
if (arr[i] == 'G' ) g_count++;
if (arr[i] == 'R' ) r_count++;
}
if (b_count == n || g_count == n || r_count == n)
return n;
if ((r_count&1) == 1)
{
if ((g_count&1) == 1)
{
if ((b_count&1) == 1)
return 2;
}
}
if ((r_count & 1) == 0)
{
if ((g_count & 1) == 0)
{
if ((b_count & 1) == 0)
return 2;
}
}
return 1;
}
public static void Main()
{
char []arr = { 'R' , 'G' , 'B' , 'R' };
int n = arr.Length;
Console.WriteLine(findMin(arr, n));
}
}
|
PHP
<?php
function findMin( $arr , $n )
{
$b_count = 0; $g_count = 0; $r_count = 0;
for ( $i = 0; $i < $n ; $i ++)
{
if ( $arr [ $i ] == 'B' ) $b_count ++;
if ( $arr [ $i ] == 'G' ) $g_count ++;
if ( $arr [ $i ] == 'R' ) $r_count ++;
}
if ( $b_count == $n || $g_count == $n ||
$r_count == $n )
return $n ;
if (( $r_count & 1 && $g_count & 1 &&
$b_count & 1))
return 2;
if (!( $r_count & 1) && !( $g_count & 1) &&
!( $b_count & 1) )
return 2;
return 1;
}
$arr = array ( 'R' , 'G' , 'B' , 'R' );
$n = count ( $arr );
echo findMin( $arr , $n );
?>
|
Javascript
<script>
function findMin(arr,n)
{
let b_count = 0, g_count = 0, r_count = 0;
for (let i = 0; i < n; i++)
{
if (arr[i] == 'B' ) b_count++;
if (arr[i] == 'G' ) g_count++;
if (arr[i] == 'R' ) r_count++;
}
if (b_count==n || g_count==n || r_count==n)
return n;
if ((r_count&1) == 1) {
if ((g_count&1) == 1) {
if ((b_count&1) == 1)
return 2;
}
}
if ((r_count & 1) == 0)
{
if ((g_count & 1) == 0)
{
if ((b_count & 1) == 0)
return 2;
}
}
return 1;
}
let arr=[ 'R' , 'G' , 'B' , 'R' ];
let n = arr.length;
document.write(findMin(arr, n));
</script>
|
Output :
1
Time complexity: O(n)
Auxiliary Space: O(1)
Exercise:
- How many transformations are needed in above problem?
- Is it possible to print the sequence in which elements transform? If yes, what will be the approach? Discuss time and space complexity
Last Updated :
11 Sep, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...