Open In App

Lexicographically smallest string with period K possible by replacing ‘?’s from a given string

Last Updated : 17 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a string S consisting of N lowercase characters and character ‘?’ and a positive integer K, the task is to replace each character ‘?’ with some lowercase alphabets such that the given string becomes a period of K. If it is not possible to do so, then print “-1”.

A string is said to be a period of K if and only if the length of the string is a multiple of K and for all possible value of i over the range [0, K) the value S[i + K], S[i + 2*K], S[i + 3*K], …, remains the same.

Examples:

Input: S = “ab??”, K = 2
Output: abab

Input: S = “??????”, K = 3
Output: aaaaaa

Naive Approach: The given approach can also be solved by generating all possible combination of strings by replacing each character ‘?’ with any lowercase characters and print that string that have each substring of size K is the same.

Time Complexity: O(26M), where M is the number of ‘?’ in the string S.
Auxiliary Space: O(1)

Efficient Approach: The above approach can also be optimized by traversing the string in a way such that the first, second, third, and so on characters are traversed and if all the characters are ‘?’ then replace it with character ‘a’, Otherwise, if there exists only one distinct character at each respective position then replace ‘?’ with that character, Otherwise, the string can’t be modified as per the given criteria and hence, print “-1”. Follow the steps below to solve the problem:

  • Iterate a loop over the range [0, K] using the variable i and perform the following steps:
    • Initialize a map, say M to store the frequency of characters of substring at positions i.
    • Traverse the given string over the range [i, N] using the variable j with an increment of K and store the frequency of the character S[j] by 1 in the map M.
    • After completing the above steps perform the following:
      • If the size of the map is greater than 2, then print “-1” and break out of the loop.
      • Otherwise, if the size of the map is 2, then replace each ‘?’ with that different character.
      • Otherwise, replace all the ‘?’ with the character ‘a’.
  • After completing the above steps, if the string can be modified, then print the string S as the result string.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include "bits/stdc++.h"
using namespace std;
 
// Function to modify the given string
// such that string S is a period of K
string modifyString(string& S, int K)
{
 
    int N = S.length();
 
    // Iterate over the range [0, K]
    for (int i = 0; i < K; i++) {
 
        // Stores the frequency of the
        // characters S[i + j*K]
        map<char, int> M;
 
        // Iterate over the string with
        // increment of K
        for (int j = i; j < N; j += K) {
            M[S[j]]++;
        }
 
        // Print "-1"
        if (M.size() > 2) {
            return "-1";
        }
        else if (M.size() == 1) {
            if (M['?'] != 0) {
 
                // Replace all characters
                // of the string with '?'
                // to 'a' to make it smallest
                for (int j = i; j < N; j += K) {
                    S[j] = 'a';
                }
            }
        }
 
        // Otherwise
        else if (M.size() == 2) {
            char ch;
 
            // Find the character other
            // than '?'
            for (auto& it : M) {
                if (it.first != '?') {
                    ch = it.first;
                }
            }
 
            // Replace all characters
            // of the string with '?'
            // to character ch
            for (int j = i; j < N; j += K) {
                S[j] = ch;
            }
        }
 
        // Clear the map M
        M.clear();
    }
 
    // Return the modified string
    return S;
}
 
// Driver Code
int main()
{
 
    string S = "ab??";
    int K = 2;
    cout << modifyString(S, K);
 
    return 0;
}


Java




// Java program for the above approach
import java.util.*;
 
class GFG{
 
  // Function to modify the given String
  // such that String S is a period of K
  static String modifyString(char[] S, int K)
  {
 
    int N = S.length;
 
    // Iterate over the range [0, K]
    for (int i = 0; i < K; i++) {
 
      // Stores the frequency of the
      // characters S[i + j*K]
      HashMap<Character,Integer> M = new HashMap<>();
 
      // Iterate over the String with
      // increment of K
      for (int j = i; j < N; j += K) {
 
        if(M.containsKey(S[j])){
          M.put(S[j], M.get(S[j])+1);
        }
        else{
          M.put(S[j], 1);
        }
      }
 
      // Print "-1"
      if (M.size() > 2) {
        return "-1";
      }
      else if (M.size() == 1) {
        if (M.get('?') != 0) {
 
          // Replace all characters
          // of the String with '?'
          // to 'a' to make it smallest
          for (int j = i; j < N; j += K) {
            S[j] = 'a';
          }
        }
      }
 
      // Otherwise
      else if (M.size() == 2) {
        char ch=' ';
 
        // Find the character other
        // than '?'
        for (Map.Entry<Character,Integer> entry : M.entrySet()) {
          if (entry.getKey() != '?') {
            ch = entry.getKey();
          }
        }
 
        // Replace all characters
        // of the String with '?'
        // to character ch
        for (int j = i; j < N; j += K) {
          S[j] = ch;
        }
      }
 
      // Clear the map M
      M.clear();
    }
 
    // Return the modified String
    return String.valueOf(S);
  }
 
  // Driver Code
  public static void main(String[] args)
  {
 
    String S = "ab??";
    int K = 2;
    System.out.print(modifyString(S.toCharArray(), K));
  }
}
 
// This code is contributed by umadevi9616


Python3




# python 3 program for the above approach
 
# Function to modify the given string
# such that string S is a period of K
def modifyString(S,K):
    N = len(S)
    S = list(S)
 
    # Iterate over the range [0, K]
    for i in range(K):
        # Stores the frequency of the
        # characters S[i + j*K]
        M = {}
 
        # Iterate over the string with
        # increment of K
        for j in range(i,N,K):
            if S[j] in M:
                M[S[j]] += 1
            else:
                M[S[j]] = 1
 
        # Print "-1"
        if (len(M) > 2):
            return "-1"
 
        elif (len(M) == 1):
            if (M['?'] != 0):
 
                # Replace all characters
                # of the string with '?'
                # to 'a' to make it smallest
                for j in range(i,N,K):
                    S[j] = 'a'
 
        # Otherwise
        elif(len(M) == 2):
            ch = ''
 
            # Find the character other
            # than '?'
            for key,value in M.items():
                if (key != '?'):
                    ch = key
            # Replace all characters
            # of the string with '?'
            # to character ch
            for j in range(i,N,K):
                S[j] = ch
 
        # Clear the map M
        M.clear()
    S = ''.join(S)
 
    # Return the modified string
    return S
 
# Driver Code
if __name__ == '__main__':
    S = "ab??"
    K = 2
    print(modifyString(S, K))
     
    # This code is contributed by ipg2016107.


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class GFG {
 
  // Function to modify the given String
  // such that String S is a period of K
  static String modifyString(char[] S, int K) {
 
    int N = S.Length;
 
    // Iterate over the range [0, K]
    for (int i = 0; i < K; i++) {
 
      // Stores the frequency of the
      // characters S[i + j*K]
      Dictionary<char, int> M = new Dictionary<char, int>();
 
      // Iterate over the String with
      // increment of K
      for (int j = i; j < N; j += K) {
 
        if (M.ContainsKey(S[j])) {
          M.Add(S[j], M[S[j]] + 1);
        } else {
          M.Add(S[j], 1);
        }
      }
 
      // Print "-1"
      if (M.Count > 2) {
        return "-1";
      } else if (M.Count == 1) {
        if (M['?'] != 0) {
 
          // Replace all characters
          // of the String with '?'
          // to 'a' to make it smallest
          for (int j = i; j < N; j += K) {
            S[j] = 'a';
          }
        }
      }
 
      // Otherwise
      else if (M.Count == 2) {
        char ch = ' ';
 
        // Find the character other
        // than '?'
        foreach (KeyValuePair<char, int> entry in M) {
          if (entry.Key != '?') {
            ch = entry.Key;
          }
        }
 
        // Replace all characters
        // of the String with '?'
        // to character ch
        for (int j = i; j < N; j += K) {
          S[j] = ch;
        }
      }
 
      // Clear the map M
      M.Clear();
    }
 
    // Return the modified String
    return String.Join("",S);
  }
 
  // Driver Code
  public static void Main(String[] args) {
 
    String S = "ab??";
    int K = 2;
    Console.Write(modifyString(S.ToCharArray(), K));
  }
}
 
// This code is contributed by umadevi9616


Javascript




<script>
 
// JavaScript program for the above approach
 
// Function to modify the given string
// such that string S is a period of K
function modifyString(S, K)
{
    let N = S.length;
 
    // Iterate over the range [0, K]
    for(let i = 0; i < K; i++)
    {
         
        // Stores the frequency of the
        // characters S[i + j*K]
        let M = new Map();
 
        // Iterate over the string with
        // increment of K
        for(let j = i; j < N; j += K)
        {
            if (M.has(S[j]))
            {
                M.set(M.get(S[j]),
                      M.get(S[j]) + 1);
            }
            else
            {
                M.set(S[j], 1);
            }
        }
 
        // Print "-1"
        if (M.size > 2)
        {
            return "-1";
        }
        else if (M.size == 1)
        {
            if (M.has('?'))
            {
                 
                // Replace all characters
                // of the string with '?'
                // to 'a' to make it smallest
                for(let j = i; j < N; j += K)
                {
                    S = S.replace(S[j], 'a');
                }
            }
        }
 
        // Otherwise
        else if (M.size == 2)
        {
            let ch;
 
            // Find the character other
            // than '?'
            for(let it of M.keys())
            {
                if (it != '?')
                {
                    ch = it;
                }
            }
 
            // Replace all characters
            // of the string with '?'
            // to character ch
            for(let j = i; j < N; j += K)
            {
                S = S.replace(S[j], ch);
            }
        }
         
        // Clear the map M
        M.clear();
    }
 
    // Return the modified string
    return S;
}
 
// Driver Code
let S = "ab??";
let K = 2;
 
document.write(modifyString(S, K));
 
// This code is contributed by Potta Lokesh
 
</script>


Output: 

abab

 

Time Complexity: O(N)
Auxiliary Space: O(N)



Similar Reads

Lexicographically smallest string formed by replacing characters according to the given relation
Given a string Str of N characters and two strings S1 and S2 of equal length where S1[i] and S2[i] are related to each other, the task is to find the lexicographically smallest string that can be obtained by replacing characters in Str with their related character. Examples: Input: S1 = "rat", S2 = "cbb", Str = "trrb"Output: accaExplanation: For th
10 min read
Make the string lexicographically smallest and non palindromic by replacing exactly one character
Given a palindromic string str containing only lowercase letters, the task is to print the lexicographically smallest string, by replacing exactly one character, such the string is not a palindrome. Examples: Input: str = "abccba" Output: "aaccba" Explanation: Lexicographically smallest non-palindromic string possible is "aaccba", here we have repl
5 min read
Lexicographically smallest string possible by performing K operations on a given string
Given a string S of size N and a positive integer K, the task is to perform atmost K operations on string S to make it lexicographically smallest possible. In one operation, swap S[i] and S[j] and then change S[i] to any character, given 1 ? i &lt; j ? N. Examples: Input: S = "geek", K = 5Output: aaaaExplanation: In 1st operation: take i = 1 and j
8 min read
Lexicographically smallest subsequence possible by removing a character from given string
Given a string S of length N, the task is to find the lexicographically smallest subsequence of length (N - 1), i.e. by removing a single character from the given string. Examples: Input: S = "geeksforgeeks"Output: "eeksforgeeks"Explanation: Lexicographically smallest subsequence possible is "eeksforgeeks". Input: S = "zxvsjas"Output: "xvsjas"Expla
8 min read
Lexicographically smallest string possible by inserting given character
Given a string S and a character C, the task is to place a character in the string in such a way that the string obtained is the lexicographically smallest string. Examples: Input: S = "acd", C = 'b'Output: "abcd"Explanation: The possible strings formed by placing the character C in string at different indices are ["bacd", "abcd", "acbd", "acdb"]Th
5 min read
Lexicographically smallest string possible by using given operations
Given a string S consisting of digits from 0 to 9 inclusive, the task is to form the lexicographically smallest string by performing an operation any number of times. In one operation you can choose any position i and delete the digit d at s[i] and insert min(d+1, 9) on any position (at the beginning, at the end, or in between any two adjacent digi
7 min read
Lexicographically largest string formed in minimum moves by replacing characters of given String
Given a string S consisting of N lowercase English characters, the task is to print the lexicographically, the largest string obtained using only the minimum number of moves needed to modify the string S to a string containing the first min(N, 26) lower case English alphabet, by replacing any character of the string S, with any lowercase English al
10 min read
Modify string by replacing all occurrences of given characters by specified replacing characters
Given a string S consisting of N lowercase alphabets and an array of pairs of characters P[][2], the task is to modify the given string S by replacing all occurrences of character P[i][0] with character P[i][1]. Examples: Input: S = "aabbgg", P[][2] = {{a, b}, {b, g}, {g, a}}Output: bbggaaExplanation:Replace 'a' by 'b' in the original string. Now t
12 min read
Generate N sized binary string with prefix S and is lexicographically smallest possible
Given a binary string S, the task is to make a binary string of size N from the given string S (don't change the position of characters) following the below conditions: The prefix of the string is S.If is the lexicographically smallest possible.Absolute difference between the number of 1s and 0s is minimum. Examples: Input: S = "101", N = 8Output:
7 min read
Lexicographically smallest string possible by merging two sorted strings
Given two sorted strings S1 and S2 of lengths N and M respectively, the task is to construct lexicographically the smallest string possible by merging the two given strings and not changing the order of occurrence of characters. Examples: Input: S1 = "eefgkors", S2 = "eegks"Output: "eeeefggkkorss"Explanation:String "eeeefggkkorss" is lexicographica
7 min read