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

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: 2
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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 curret 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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 curret 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 curret 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

chevron_right


Output:

2


My Personal Notes arrow_drop_up

Striver(underscore)79 at Codechef and codeforces D

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 Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : princiraj1992, Ryuga