Skip to content
Related Articles

Related Articles

Improve Article

Lexicographically shortest string of length at most K which is not a substring of given String

  • Difficulty Level : Medium
  • Last Updated : 18 Aug, 2021
Geek Week

Given a string S, the task is to find the lexicographically shortest string of length less than or equal to K which is not a substring of the given string. If not possible, print -1.

Examples:

Input: S = zxabcehgf, K = 2
Output: d
Explanation: Lexicographically, the shortest string which is not a substring of a given string is d.

Input: S = sdhaacbdefghijklmnopqrstuvwxyz, K = 3
Output: ab

Approach: The problem can be solved by finding all the substrings of given string S which have length less than or equal to K. Then start from the lexicographically smallest stringa‘, and keep forming the next string till we do not find the answer. Follow the steps below to solve the problem.

  • Initialize a set of strings, say st, to store all the substrings of length at most K.
  • Iterate from 1 to K to create all strings possible lengths from 1 to K.
  • Check if the current string formed is present in the set or not. If not, then print it and return.
  • Otherwise, form the next lexicographical string and repeat the process until an answer is found.

Below is the implementation of the above approach.



C++




// C++ implementation for above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to return a set of all
// substrings of given string which have
// length less than or equal to k
set<string> presentSubstring(string s, int k)
{
    set<string> st;
    int n = s.length();
 
    for (int i = 0; i < n; i++) {
        string s1 = "";
 
        for (int j = 0; j < k && i + j < n; j++) {
            s1.push_back(s[i + j]);
 
            st.insert(s1);
        }
    }
 
    return st;
}
 
// Function to print the lexicographically
// smallest substring of length atmost k
// which is not present in given string s
string smallestSubstring(string s, int k)
{
    set<string> st;
 
    // All substrings of length atmost k
    // present in string s are stored in
    // this set
    st = presentSubstring(s, k);
 
    int index;
 
    // Loop to change length of substring
    for (int len = 1; len <= k; len++) {
 
        // String with length=len which has
        // all characters as 'a'
        string t(len, 'a');
 
        while (true) {
 
            // If the substrings set does
            // not contain this string then
            // we have found the answer
            if (st.count(t) == 0) {
                return t;
            }
 
            index = len - 1;
 
            // Changing the likes of 'azz'
            // and 'daz' to 'baa' and 'dba'
            // respectively
            while (index >= 0 && t[index] == 'z') {
                t[index] = 'a';
                index--;
            }
 
            if (index >= 0)
                t[index]++;
 
            // Reached a string like 'zz'
            // or 'zzz' increase the length
            // of the substring
            else
                break;
        }
    }
    return "-1";
}
 
// Driver Code
int main()
{
 
    // Given Input
    string s = "sdhaacbdefghijklmnopqrstuvwxyz";
    int K = 3;
 
    // Function Call
    cout << smallestSubstring(s, K) << endl;
 
    return 0;
}

Java




// Java implementation for above approach
import java.util.*;
 
class GFG
{
 
// Function to return a set of all
// subStrings of given String which have
// length less than or equal to k
static HashSet<String> presentSubString(String s, int k)
{
    HashSet<String> st = new HashSet<String>();
    int n = s.length();
 
    for (int i = 0; i < n; i++) {
        String s1 = "";
 
        for (int j = 0; j < k && i + j < n; j++) {
            s1 += s.charAt(i + j);
 
            st.add(s1);
        }
    }
 
    return st;
}
 
// Function to print the lexicographically
// smallest subString of length atmost k
// which is not present in given String s
static String smallestSubString(String s, int k)
{
    HashSet<String> st = new HashSet<String>();
 
    // All subStrings of length atmost k
    // present in String s are stored in
    // this set
    st = presentSubString(s, k);
 
    int index;
 
    // Loop to change length of subString
    for (int len = 1; len <= k; len++) {
 
        // String with length=len which has
        // all characters as 'a'
        String t = "";
        for(int i=0;i<len;i++)
            t+='a';
 
        while (true) {
 
            // If the subStrings set does
            // not contain this String then
            // we have found the answer
            if (!st.contains(t)) {
                return t;
            }
 
            index = len - 1;
 
            // Changing the likes of 'azz'
            // and 'daz' to 'baa' and 'dba'
            // respectively
            while (index >= 0 && t.charAt(index) == 'z') {
                t=t.substring(0,index)+'a'+t.substring(index+1);
                index--;
            }
             
            if (index >= 0)
                t=t.substring(0,index)+ (char)((t.charAt(index))+1) + t.substring(index+1);
 
            // Reached a String like 'zz'
            // or 'zzz' increase the length
            // of the subString
            else
                break;
        }
    }
    return "-1";
}
 
// Driver Code
public static void main(String[] args)
{
 
    // Given Input
    String s = "sdhaacbdefghijklmnopqrstuvwxyz";
    int K = 3;
 
    // Function Call
    System.out.print(smallestSubString(s, K) +"\n");
}
}
 
// This code is contributed by shikhasingrajput

Python3




# Python 3 implementation for above approach
 
# Function to return a set of all
# substrings of given string which have
# length less than or equal to k
def presentSubstring(s, k):
    st = set()
    n = len(s)
    s = list(s)
 
    for i in range(n):
        s1 = ""
        j = 0
        while(j < k and i + j < n):
            s1 += s[i + j]
 
            st.add(s1)
            j += 1
     
    s = ''.join(s)
    return st
 
# Function to print the lexicographically
# smallest substring of length atmost k
# which is not present in given string s
def smallestSubstring(s, k):
    st = set()
 
    # All substrings of length atmost k
    # present in string s are stored in
    # this set
    st = presentSubstring(s, k)
 
    index = 0
 
    # Loop to change length of substring
    for len1 in range(1,k+1,1):
        # String with length=len which has
        # all characters as 'a'
        t = []
        for x in range(len1):
            t.append('a')
 
        while (True):
            # If the substrings set does
            # not contain this string then
            # we have found the answer
            if (''.join(t) not in st):
                return ''.join(t)
 
            index = len1 - 1
 
            # Changing the likes of 'azz'
            # and 'daz' to 'baa' and 'dba'
            # respectively
            while (index >= 0 and t[index] == 'z'):
                t[index] = 'a'
                index -= 1
 
            if (index >= 0):
                t[index] = chr(ord(t[index])+1)
 
            # Reached a string like 'zz'
            # or 'zzz' increase the length
            # of the substring
            else:
                break
    return "-1"
 
# Driver Code
if __name__ == '__main__':
    # Given Input
    s = "sdhaacbdefghijklmnopqrstuvwxyz"
    K = 3
 
    # Function Call
    print(smallestSubstring(s, K))
     
    # This code is contributed by ipg2016107.

C#




// C# implementation for above approach
using System;
using System.Collections.Generic;
 
class GFG {
 
    // Function to return a set of all
    // substrings of given string which have
    // length less than or equal to k
    static HashSet<string> presentSubstring(string s, int k)
    {
        HashSet<string> st = new HashSet<string>();
        int n = s.Length;
 
        for (int i = 0; i < n; i++) {
            string s1 = "";
 
            for (int j = 0; j < k && i + j < n; j++) {
                s1 += s[i + j];
 
                st.Add(s1);
            }
        }
 
        return st;
    }
 
    // Function to print the lexicographically
    // smallest substring of length atmost k
    // which is not present in given string s
    static string smallestSubstring(string s, int k)
    {
        HashSet<string> st = new HashSet<string>();
 
        // All substrings of length atmost k
        // present in string s are stored in
        // this set
        st = presentSubstring(s, k);
 
        int index;
 
        // Loop to change length of substring
        for (int len = 1; len <= k; len++) {
 
            // String with length=len which has
            // all characters as 'a'
            string t = "";
            for (int i = 0; i < len; i++)
                t += 'a';
 
            while (true) {
 
                // If the substrings set does
                // not contain this string then
                // we have found the answer
                if (st.Contains(t)==false) {
                    return t;
                }
 
                index = len - 1;
 
                // Changing the likes of 'azz'
                // and 'daz' to 'baa' and 'dba'
                // respectively
                while (index >= 0 && t[index] == 'z') {
                    t = t.Substring(0, index) + 'a'
                        + t.Substring(index + 1);
                    index--;
                }
 
                if (index >= 0) {
                    t = t.Substring(0, index)
                        + Convert.ToChar((int)t[index] + 1)
                        + t.Substring(index + 1);
                }
 
                // Reached a string like 'zz'
                // or 'zzz' increase the length
                // of the substring
                else
                    break;
            }
           // t += 'b';
        }
        return "-1";
    }
 
    // Driver Code
    public static void Main()
    {
 
        // Given Input
        string s = "sdhaacbdefghijklmnopqrstuvwxyz";
        int K = 3;
 
        // Function Call
        Console.Write(smallestSubstring(s, K));
    }
}
 
// This code is contributed by ipg2016107.

Javascript




<script>
// Javascript implementation for above approach
 
// Function to return a set of all
// substrings of given string which have
// length less than or equal to k
function presentSubstring(s, k) {
  let st = new Set();
  let n = s.length;
  s = s.split("");
 
  for (let i = 0; i < n; i++) {
    let s1 = "";
 
    for (let j = 0; j < k && i + j < n; j++) {
      s1 += s[i + j];
 
      st.add(s1);
    }
  }
 
  return st;
}
 
// Function to print the lexicographically
// smallest substring of length atmost k
// which is not present in given string s
function smallestSubstring(s, k) {
  let st = new Set();
 
  // All substrings of length atmost k
  // present in string s are stored in
  // this set
  st = presentSubstring(s, k);
 
  let index = 0;
 
  // Loop to change length of substring
  for (let len = 1; len <= k; len++)
  {
   
    // String with length=len which has
    // all characters as 'a'
    let t = new Array(len).fill("a");
 
    while (true)
    {
     
      // If the substrings set does
      // not contain this string then
      // we have found the answer
 
      if (!st.has(t.join(""))) {
        return t.join("");
      }
 
      index = len - 1;
 
      // Changing the likes of 'azz'
      // and 'daz' to 'baa' and 'dba'
      // respectively
      while (index >= 0 && t[index] == "z") {
        t[index] = "a";
        index--;
      }
 
      if (index >= 0)
        t[index] = String.fromCharCode(t[index].charCodeAt(0) + 1);
         
      // Reached a string like 'zz'
      // or 'zzz' increase the length
      // of the substring
      else break;
    }
  }
  return "-1";
}
 
// Driver Code
 
// Given Input
let s = "sdhaacbdefghijklmnopqrstuvwxyz";
let K = 3;
 
// Function Call
document.write(smallestSubstring(s, K));
 
// This code is contributed by _saurabh_jaiswal.
</script>
Output
ab

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

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
Recommended Articles
Page :