Skip to content
Related Articles

Related Articles

Improve Article

Minimum replacements to make adjacent characters unequal in a ternary string | Set-2

  • Last Updated : 27 May, 2021

Given a string of ‘0’, ‘1’ and ‘2’. The task is to find the minimum number of replacements such that the adjacent characters are not equal. 
Examples: 
 

Input: s = “201220211” 
Output:
Resultant string after changes is 201210210
Input: s = “0120102” 
Output: 0

 

Approach: The problem has been solved using a greedy approach in the previous post. In this post, we will discuss a Dynamic Programming approach to solve the same problem. Create a function charVal which returns 0, 1 or 2 depending on the character. 
A recursive function is made which calls the charVal function to get the i-th value, and if this is equal to the previous one, then only the other two states (1 or 2, 0 or 1, 0 or 2) is used at i-th character. If it is not equal to the previous one, no changes are made. A dp[][] array is used for memoization. The base case is when all the positions are filled. If any of the state is re-visited, then return the value that is stored in dp[][] array. DP[i][j] means that i-th position is filled with j-th character. 
Below is the implementation of the above problem: 
 

C++




// C++ program to count the minimal
// replacements such that adjacent characters
// are unequal
#include <bits/stdc++.h>
using namespace std;
 
// function to return integer value
// of i-th character in the string
int charVal(string s, int i)
{
    if (s[i] == '0')
        return 0;
    else if (s[i] == '1')
        return 1;
    else
        return 2;
}
 
// Function to count the number of
// minimal replacements
int countMinimalReplacements(string s, int i,
                        int prev, int dp[][3], int n)
{
 
    // If the string has reached the end
    if (i == n) {
        return 0;
    }
 
    // If the state has been visited previously
    if (dp[i][prev] != -1)
        return dp[i][prev];
 
    // Get the current value of character
    int val = charVal(s, i);
    int ans = INT_MAX;
 
    // If it is equal then change it
    if (val == prev) {
        int val = 0;
 
        // All possible changes
        for (int cur = 0; cur <= 2; cur++) {
            if (cur == prev)
                continue;
 
            // Change done
            val = 1 + countMinimalReplacements(s, i + 1, cur, dp, n);
 
            ans = min(ans, val);
        }
    }
    else // If same no change
        ans = countMinimalReplacements(s, i + 1, val, dp, n);
 
    return dp[i][val] = ans;
}
 
// Driver Code
int main()
{
    string s = "201220211";
 
    // Length of string
    int n = s.length();
 
    // Create a DP array
    int dp[n][3];
 
    memset(dp, -1, sizeof dp);
 
    // First character
    int val = charVal(s, 0);
 
    // Function to find minimal replacements
    cout << countMinimalReplacements(s, 1, val, dp, n);
    return 0;
}

Java




// Java program to count the minimal
// replacements such that adjacent characters
// are unequal
class GFG
{
 
    // function to return integer value
    // of i-th character in the string
    static int charVal(String s, int i)
    {
        if (s.charAt(i) == '0')
        {
            return 0;
        }
        else if (s.charAt(i) == '1')
        {
            return 1;
        }
        else
        {
            return 2;
        }
    }
 
    // Function to count the number of
    // minimal replacements
    static int countMinimalReplacements(String s, int i,
                            int prev, int dp[][], int n)
    {
 
        // If the string has reached the end
        if (i == n)
        {
            return 0;
        }
 
        // If the state has been visited previously
        if (dp[i][prev] != -1)
        {
            return dp[i][prev];
        }
 
        // Get the current value of character
        int val = charVal(s, i);
        int ans = Integer.MAX_VALUE;
 
        // If it is equal then change it
        if (val == prev)
        {
            val = 0;
 
            // All possible changes
            for (int cur = 0; cur <= 2; cur++)
            {
                if (cur == prev)
                {
                    continue;
                }
 
                // Change done
                val = 1 + countMinimalReplacements(s,
                                    i + 1, cur, dp, n);
 
                ans = Math.min(ans, val);
            }
        } else // If same no change
        {
            ans = countMinimalReplacements(s, i + 1,
                                        val, dp, n);
        }
 
        return dp[i][val] = ans;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        String s = "201220211";
 
        // Length of string
        int n = s.length();
 
        // Create a DP array
        int dp[][] = new int[n][3];
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                dp[i][j] = -1;
            }
        }
 
        // First character
        int val = charVal(s, 0);
 
        // Function to find minimal replacements
        System.out.println(countMinimalReplacements(s, 1,
                                            val, dp, n));
    }
}
 
// This code is contributed by PrinciRaj1992

Python3




# Python 3 program to count the minimal
# replacements such that adjacent characters
# are unequal
import sys
 
# function to return integer value
# of i-th character in the string
def charVal(s, i):
    if (s[i] == '0'):
        return 0
    elif (s[i] == '1'):
        return 1
    else:
        return 2
 
# Function to count the number of
# minimal replacements
def countMinimalReplacements(s,i,prev, dp, n):
     
    # If the string has reached the end
    if (i == n):
        return 0
 
    # If the state has been visited previously
    if (dp[i][prev] != -1):
        return dp[i][prev]
 
    # Get the current value of character
    val = charVal(s, i)
    ans = sys.maxsize
 
    # If it is equal then change it
    if (val == prev):
        val = 0
 
        # All possible changes
        for cur in range(3):
            if (cur == prev):
                continue
 
            # Change done
            val = 1 + countMinimalReplacements(s, i + 1, cur, dp, n)
            ans = min(ans, val)
             
        # If same no change
    else:
        ans = countMinimalReplacements(s, i + 1, val, dp, n)
 
    dp[i][val] = ans
 
    return dp[i][val]
 
# Driver Code
if __name__ == '__main__':
    s = "201220211"
 
    # Length of string
    n = len(s)
 
    # Create a DP array
    dp = [[-1 for i in range(3)] for i in range(n)]
 
    # First character
    val = charVal(s, 0)
 
    # Function to find minimal replacements
    print(countMinimalReplacements(s, 1, val, dp, n))
     
# This code is contributed by
# Surendra_Gangwar

C#




// C# program to count the minimal
// replacements such that adjacent
// characters are unequal
using System;
 
class GFG
{
 
    // function to return integer value
    // of i-th character in the string
    static int charVal(string s, int i)
    {
        if (s[i] == '0')
        {
            return 0;
        }
        else if (s[i] == '1')
        {
            return 1;
        }
        else
        {
            return 2;
        }
    }
 
    // Function to count the number of
    // minimal replacements
    static int countMinimalReplacements(string s, int i,
                            int prev, int [,]dp, int n)
    {
 
        // If the string has reached the end
        if (i == n)
        {
            return 0;
        }
 
        // If the state has been visited previously
        if (dp[i,prev] != -1)
        {
            return dp[i,prev];
        }
 
        // Get the current value of character
        int val = charVal(s, i);
        int ans = int.MaxValue;
 
        // If it is equal then change it
        if (val == prev)
        {
            val = 0;
 
            // All possible changes
            for (int cur = 0; cur <= 2; cur++)
            {
                if (cur == prev)
                {
                    continue;
                }
 
                // Change done
                val = 1 + countMinimalReplacements(s,
                                    i + 1, cur, dp, n);
 
                ans = Math.Min(ans, val);
            }
        }
        else // If same no change
        {
            ans = countMinimalReplacements(s, i + 1,
                                        val, dp, n);
        }
 
        return dp[i,val] = ans;
    }
 
    // Driver Code
    public static void Main()
    {
        string s = "201220211";
 
        // Length of string
        int n = s.Length;
 
        // Create a DP array
        int [,]dp = new int[n,3];
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                dp[i,j] = -1;
            }
        }
 
        // First character
        int val = charVal(s, 0);
 
        // Function to find minimal replacements
        Console.WriteLine(countMinimalReplacements(s, 1,
                                            val, dp, n));
    }
}
 
// This code is contributed by Ryuga

Javascript




<script>
 
// JavaScript program to count the minimal
// replacements such that adjacent characters
// are unequal   
 
// function to return integer value
    // of i-th character in the string
    function charVal( s , i) {
        if (s.charAt(i) == '0') {
            return 0;
        } else if (s.charAt(i) == '1') {
            return 1;
        } else {
            return 2;
        }
    }
 
    // Function to count the number of
    // minimal replacements
    function countMinimalReplacements( s , i , prev , dp , n)
    {
 
        // If the string has reached the end
        if (i == n) {
            return 0;
        }
 
        // If the state has been visited previously
        if (dp[i][prev] != -1) {
            return dp[i][prev];
        }
 
        // Get the current value of character
        var val = charVal(s, i);
        var ans = Number.MAX_VALUE;
 
        // If it is equal then change it
        if (val == prev) {
            val = 0;
 
            // All possible changes
            for (var cur = 0; cur <= 2; cur++) {
                if (cur == prev) {
                    continue;
                }
 
                // Change done
                val = 1 +
                countMinimalReplacements(s, i + 1, cur, dp, n);
 
                ans = Math.min(ans, val);
            }
        } else // If same no change
        {
            ans =
            countMinimalReplacements(s, i + 1, val, dp, n);
        }
 
        return dp[i][val] = ans;
    }
 
    // Driver Code
     
        var s = "201220211";
 
        // Length of string
        var n = s.length;
 
        // Create a DP array
        var dp = Array(n).fill().map(()=>Array(3).fill(0));
        for (var i = 0; i < n; i++) {
            for (var j = 0; j < 3; j++) {
                dp[i][j] = -1;
            }
        }
 
        // First character
        var val = charVal(s, 0);
 
        // Function to find minimal replacements
 document.write(countMinimalReplacements(s, 1, val, dp, n));
 
// This code contributed by Rajput-Ji
 
</script>
Output: 
2

 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up