# Smallest length string with repeated replacement of two distinct adjacent

Given a string of any combination of three letters ‘a’, ‘b’, and ‘c’, find length of the smallest string that can be obtained by applying the following operation repeatedly:

*Take any two adjacent, distinct characters and replace them with the third.*

**Examples:**

Input : cab Output : 2 We can select any two adjacent letters, say 'ca' and transform it into 'b', this leaves us with string 'bb' of length two. Input : bcab Output : 1 Selecting 'bc' and transforming it to 'a' leaves us with 'aab'. We can then select 'ab' and transform it to 'c', giving 'ac'. This can further be transformed into 'b', which is of length one.

A naive way to do this would be to find all possible replacements, and recurse until we find the minimum string. This would take exponential time.

**Lemma**: Order of letters does not effect the length or value of minimum string.

**Proof By Induction**

**Base case**: Take string ‘ab’ and ‘ba’, they both reduce to ‘c’

**Inductive Hypothesis**: All strings of length <= k reduce to the same string assuming the number of occurrences of each letter in each string is the same.

**Inductive Step**: Take two strings of length k + 1 having same number of occurrences of each letter. Find a pair of letters that are adjacent

in both strings. Here, two cases arise:

- We manage to find such a pair of letters. We can then replace these letters with the third letter, thus getting two strings of length k having same occurrences of each letter, which by inductive hypothesis reduces to the same string. i.e. We have ‘abcacb’ and ‘accbba’ and reduce ‘ac’ in both strings, we thus get ‘abcbb’ and ‘bcbba’.
- We cannot find such a pair. This arises when all letters in the string are the same. In this case, the two strings themselves are the same i.e. ‘ccccccc’ and ‘ccccccc’.

Thus by induction we have proven this lemma.

**Dynamic Programming Approach**

We can now devise a function using Dynamic Programming to solve this problem.

`// C++ program to find smallest possible length ` `// of a string of only three characters ` `#include<bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `// Program to find length of reduced string ` `// in a string made of three characters. ` `#define MAX_LEN 110 ` ` ` `// To store results of subproblems ` `int` `DP[MAX_LEN][MAX_LEN][MAX_LEN]; ` ` ` `// A memoized function find result recursively. ` `// a, b and c are counts of 'a's, 'b's and ` `// 'c's in str ` `int` `length(` `int` `a, ` `int` `b, ` `int` `c) ` `{ ` ` ` `// If this subproblem is already evaluated ` ` ` `if` `(DP[a][b] != -1) ` ` ` `return` `DP[a][b]; ` ` ` ` ` `// If there is only one type of character ` ` ` `if` `(a == 0 && b == 0) ` ` ` `return` `(DP[a][b] = c); ` ` ` `if` `(a == 0 && c == 0) ` ` ` `return` `(DP[a][b] = b); ` ` ` `if` `(b == 0 && c == 0) ` ` ` `return` `(DP[a][b] = a); ` ` ` ` ` `// If only two types of characters are present ` ` ` `if` `(a == 0) ` ` ` `return` `(DP[a][b] = ` ` ` `length(a + 1, b - 1, c - 1)); ` ` ` `if` `(b == 0) ` ` ` `return` `(DP[a][b] = ` ` ` `length(a - 1, b + 1, c - 1)); ` ` ` `if` `(c == 0) ` ` ` `return` `(DP[a][b] = ` ` ` `length(a - 1, b - 1, c + 1)); ` ` ` ` ` `// If all types of characters are present. ` ` ` `// Try combining all pairs. ` ` ` `return` `(DP[a][b] = ` ` ` `min(length(a - 1, b - 1, c + 1), ` ` ` `min(length(a - 1, b + 1, c - 1), ` ` ` `length(a + 1, b - 1, c - 1)))); ` `} ` ` ` `// Returns smallest possible length with given ` `// operation allowed. ` `int` `stringReduction(string str) ` `{ ` ` ` `int` `n = str.length(); ` ` ` ` ` `// Counting occurrences of three different ` ` ` `// characters 'a', 'b' and 'c' in str ` ` ` `int` `count[3] = {0}; ` ` ` `for` `(` `int` `i=0; i<n; ++i) ` ` ` `count[str[i]-` `'a'` `]++; ` ` ` ` ` `// Initialize DP[][] entries as -1 ` ` ` `for` `(` `int` `i = 0; i <= count[0]; ++i) ` ` ` `for` `(` `int` `j = 0; j < count[1]; ++j) ` ` ` `for` `(` `int` `k = 0; k < count[2]; ++k) ` ` ` `DP[i][j][k] = -1; ` ` ` ` ` `return` `length(count[0], count[1], count[2]); ` `} ` ` ` `// Driver code ` `int` `main() ` `{ ` ` ` `string str = ` `"abcbbaacb"` `; ` ` ` `cout << stringReduction(str); ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

**Output:**

1

In the worst case, each letter is present in 1/3rd of the whole string. This leads to auxiliary space = O(N^{3}) and time complexity = O(N^{3})

Space Complexity = O(N^3) Time Complexity = O(N^3)

**Mathematical Approach**

We can do better than this using three main principles:

- If the string cannot be reduced further, then all letters in the string are the same.
- The length of minimum string is either <= 2 or equal to the length of original string, or 2 < minimum string length < original string length is never true.
- If each letter of the string is present an odd amount of times, after one reduction step, they shall all be present an even amount of times. The converse is also true, that is, if each letter of the string is present an even amount of times, they shall be present an odd amount of times after one reduction step.

These can be proven as follows:

- If any two different letters are present, we can select these and reduce string length further.
- Proof by contradiction:

Assume we have a reduced string of length less than original string. For example 'bbbbbbb'. Then this string must have originated from a string like 'acbbbbbb', 'bbacbbbb' or any other such combination of the same. In this case, we could have selected 'bc' instead of 'ac' and reduced further. - From the recursive step above, we increase one letter by one and decrease the other two by one. So if we had a combination as (odd, odd, odd), then it would become (odd + 1, odd – 1, odd – 1) or (even, even, even). The reverse is shown in a similar fashion.

Now we can combine the above principles.

If the string consists of the same letter repeating, it's minimum reduced string is itself, and length is the length of the string.

Now, the other possible options are reduced string being of one character length or two. Now if all characters are present an even number of times, or an odd number of times, the only answer that is possible is 2, because (0, 2, 0) is (even, even, even) while (0, 1, 0) is (even, odd, even) so only 2 preserves this evenness.

In any other condition, the answer becomes 1.

## C++

`// C++ program to find smallest possible length ` `// of a string of only three characters ` `#include<bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `// Returns smallest possible length with given ` `// operation allowed. ` `int` `stringReduction(string str) ` `{ ` ` ` `int` `n = str.length(); ` ` ` ` ` `// Counint occurrences of three different ` ` ` `// characters 'a', 'b' and 'c' in str ` ` ` `int` `count[3] = {0}; ` ` ` `for` `(` `int` `i=0; i<n; ++i) ` ` ` `count[str[i]-` `'a'` `]++; ` ` ` ` ` `// If all characters are same. ` ` ` `if` `(count[0] == n || count[1] == n || ` ` ` `count[2] == n) ` ` ` `return` `n; ` ` ` ` ` `// If all characters are present even number ` ` ` `// of times or all are present odd number of ` ` ` `// times. ` ` ` `if` `((count[0] % 2) == (count[1] % 2) && ` ` ` `(count[1] % 2) == (count[2] % 2)) ` ` ` `return` `2; ` ` ` ` ` `// Answer is 1 for all other cases. ` ` ` `return` `1; ` `} ` ` ` `// Driver code ` `int` `main() ` `{ ` ` ` `string str = ` `"abcbbaacb"` `; ` ` ` `cout << stringReduction(str); ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

## Java

`// Java program to find smallest possible length ` `// of a string of only three characters ` `public` `class` `GFG { ` ` ` `// Returns smallest possible length with given ` `// operation allowed. ` ` ` `static` `int` `stringReduction(String str) { ` ` ` `int` `n = str.length(); ` ` ` ` ` `// Counint occurrences of three different ` ` ` `// characters 'a', 'b' and 'c' in str ` ` ` `int` `count[] = ` `new` `int` `[` `3` `]; ` ` ` `for` `(` `int` `i = ` `0` `; i < n; ++i) { ` ` ` `count[str.charAt(i) - ` `'a'` `]++; ` ` ` `} ` ` ` ` ` `// If all characters are same. ` ` ` `if` `(count[` `0` `] == n || count[` `1` `] == n ` ` ` `|| count[` `2` `] == n) { ` ` ` `return` `n; ` ` ` `} ` ` ` ` ` `// If all characters are present even number ` ` ` `// of times or all are present odd number of ` ` ` `// times. ` ` ` `if` `((count[` `0` `] % ` `2` `) == (count[` `1` `] % ` `2` `) ` ` ` `&& (count[` `1` `] % ` `2` `) == (count[` `2` `] % ` `2` `)) { ` ` ` `return` `2` `; ` ` ` `} ` ` ` ` ` `// Answer is 1 for all other cases. ` ` ` `return` `1` `; ` ` ` `} ` ` ` `// Driver code ` ` ` `public` `static` `void` `main(String[] args) { ` ` ` `String str = ` `"abcbbaacb"` `; ` ` ` `System.out.println(stringReduction(str)); ` ` ` `} ` `} ` `// This code is contributed by PrinciRaj1992 ` |

*chevron_right*

*filter_none*

## Python 3

`# Python 3 program to find smallest possible ` `# length of a string of only three characters ` ` ` `# Returns smallest possible length ` `# with given operation allowed. ` `def` `stringReduction(` `str` `): ` ` ` ` ` `n ` `=` `len` `(` `str` `) ` ` ` ` ` `# Counint occurrences of three different ` ` ` `# characters 'a', 'b' and 'c' in str ` ` ` `count ` `=` `[` `0` `] ` `*` `3` ` ` `for` `i ` `in` `range` `(n): ` ` ` `count[` `ord` `(` `str` `[i]) ` `-` `ord` `(` `'a'` `)] ` `+` `=` `1` ` ` ` ` `# If all characters are same. ` ` ` `if` `(count[` `0` `] ` `=` `=` `n ` `or` `count[` `1` `] ` `=` `=` `n ` `or` ` ` `count[` `2` `] ` `=` `=` `n): ` ` ` `return` `n ` ` ` ` ` `# If all characters are present even number ` ` ` `# of times or all are present odd number of ` ` ` `# times. ` ` ` `if` `((count[` `0` `] ` `%` `2` `) ` `=` `=` `(count[` `1` `] ` `%` `2` `) ` `and` ` ` `(count[` `1` `] ` `%` `2` `) ` `=` `=` `(count[` `2` `] ` `%` `2` `)): ` ` ` `return` `2` ` ` ` ` `# Answer is 1 for all other cases. ` ` ` `return` `1` ` ` `# Driver code ` `if` `__name__ ` `=` `=` `"__main__"` `: ` ` ` ` ` `str` `=` `"abcbbaacb"` ` ` `print` `(stringReduction(` `str` `)) ` ` ` `# This code is contributed by ita_c ` |

*chevron_right*

*filter_none*

## C#

`// C# program to find smallest possible length ` `// of a string of only three characters ` `using` `System; ` `public` `class` `GFG { ` ` ` `// Returns smallest possible length with given ` `// operation allowed. ` ` ` `static` `int` `stringReduction(String str) { ` ` ` `int` `n = str.Length; ` ` ` ` ` `// Counint occurrences of three different ` ` ` `// characters 'a', 'b' and 'c' in str ` ` ` `int` `[]count = ` `new` `int` `[3]; ` ` ` `for` `(` `int` `i = 0; i < n; ++i) { ` ` ` `count[str[i] - ` `'a'` `]++; ` ` ` `} ` ` ` ` ` `// If all characters are same. ` ` ` `if` `(count[0] == n || count[1] == n ` ` ` `|| count[2] == n) { ` ` ` `return` `n; ` ` ` `} ` ` ` ` ` `// If all characters are present even number ` ` ` `// of times or all are present odd number of ` ` ` `// times. ` ` ` `if` `((count[0] % 2) == (count[1] % 2) ` ` ` `&& (count[1] % 2) == (count[2] % 2)) { ` ` ` `return` `2; ` ` ` `} ` ` ` ` ` `// Answer is 1 for all other cases. ` ` ` `return` `1; ` ` ` `} ` ` ` `// Driver code ` ` ` `public` `static` `void` `Main() { ` ` ` `String str = ` `"abcbbaacb"` `; ` ` ` `Console.WriteLine(stringReduction(str)); ` ` ` `} ` `} ` `// This code is contributed by 29AjayKumar ` |

*chevron_right*

*filter_none*

## PHP

`<?php ` `// PHP program to find smallest possible length ` `// of a string of only three characters ` ` ` `// Returns smallest possible length with ` `// given operation allowed. ` `function` `stringReduction(` `$str` `) ` `{ ` ` ` `$n` `= ` `strlen` `(` `$str` `); ` ` ` ` ` `// Counint occurrences of three different ` ` ` `// characters 'a', 'b' and 'c' in str ` ` ` `$count` `= ` `array_fill` `(0, 3, 0); ` ` ` `for` `(` `$i` `= 0; ` `$i` `< ` `$n` `; ++` `$i` `) ` ` ` `$count` `[ord(` `$str` `[` `$i` `]) - ord(` `'a'` `)]++; ` ` ` ` ` `// If all characters are same. ` ` ` `if` `(` `$count` `[0] == ` `$n` `|| ` `$count` `[1] == ` `$n` `|| ` ` ` `$count` `[2] == ` `$n` `) ` ` ` `return` `$n` `; ` ` ` ` ` `// If all characters are present even number ` ` ` `// of times or all are present odd number of ` ` ` `// times. ` ` ` `if` `((` `$count` `[0] % 2) == (` `$count` `[1] % 2) && ` ` ` `(` `$count` `[1] % 2) == (` `$count` `[2] % 2)) ` ` ` `return` `2; ` ` ` ` ` `// Answer is 1 for all other cases. ` ` ` `return` `1; ` `} ` ` ` `// Driver code ` `$str` `= ` `"abcbbaacb"` `; ` `print` `(stringReduction(` `$str` `)); ` ` ` `// This code is contributed by mits ` `?> ` |

*chevron_right*

*filter_none*

**Output:**

1

**Time Complexity:** O(n)

**Auxiliary Space:** O(1)

This article is contributed by **Aditya Kamath**. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

## Recommended Posts:

- Length of the smallest sub-string consisting of maximum distinct characters
- Generate lexicographically smallest string of 0, 1 and 2 with adjacent swaps allowed
- Smallest Greater (than S) String of length K whose letters are subset of S
- String with k distinct characters and no same characters adjacent
- Smallest Palindrome after replacement
- Repeated subsequence of length 2 or more
- Number of ways to form an array with distinct adjacent elements
- Character replacement after removing duplicates from a string
- Number of Binary Strings of length N with K adjacent Set Bits
- Maximum length subsequence with difference between adjacent elements as either 0 or 1
- Check if a string can be repeated to make another string
- Length of the longest increasing subsequence such that no two adjacent elements are coprime
- Minimum length substring with exactly K distinct characters
- Minimum length of the sub-string whose characters can be used to form a palindrome of length K
- Print all distinct circular strings of length M in lexicographical order