Smallest string divisible by two given Strings


The objective of this article is to determine the smallest string that is a multiple of both given strings. An interesting observation to note is that for two given strings s and t, the string s is a multiple of t if and only if s can be formed by repeating t one or more times. We have to find the smallest such string.

Problem Statement

Given two non-empty strings, s1 and s2, with lengths n and m respectively, the objective is to determine the smallest string that is a multiple of both s1 and s2.

A string x is divisible by a string y if there exists a string z such that x = yz. In other words, y is a factor of x. A string that is divisible by both s and t must be a multiple of their greatest common divisor (GCD).

Example

Input: s1 = “abab”, s2 = “ab”
Output: abab

Explanation

s1 = s2 + s2. Therefore, the smallest string divisible is s1 itself.

Input: s1 = “abcdef”, s2 = “z”
Output: -1

Explanation

The GCD of s1 and s2 does not exist so no such output exists.

Input: s1 = “aaaaa”, s2 = “aca”
Output: -1

Explanation

The GCD of s1 and s2 does not exist so no such output exists.

Solution Approach

A brute force approach for finding the string with the shortest length that is a multiple of both strings S and T is to generate all possible combinations of the two strings and check if each combination is divisible by both S and T. We can start by generating all possible substrings of S and T, and then concatenate them to form all possible combinations.

Once we have generated all possible combinations, we can check each combination to see if it is divisible by both S and T. To determine whether a string is divisible by another string, we can use the modulo operator to check if the remainder is zero when we divide the string by the other string.

The time complexity of this brute force approach is O(N^3), where N denotes the length of the input strings. This approach is inefficient for large input sizes, so we use the more efficient approach based on the concept of Greatest Common Divisor GCD instead.

Steps

  • Declare and initialize a function named "findSmallestString" which intakes strings "s" and "t" as input in the form of parameters.

  • Initialize two integers "n" and "m" with the length of strings "s" and "t" respectively

  • Calculate the LCM of "n" and "m" using the "lcm" function

  • Concatenate strings "s" and "t" to form a new string "st"

  • Initialize an empty string named "result"

  • Traverse through the strings "s" and "t" until a mismatch is found. Append the matching characters to the "result" string.

  • If the length of both strings is equal, output string "s" and exit the function

  • If the length of "s" is greater than "t", swap the values of "n" and "m" and the values of "s" and "t"

  • Extract the remaining part of "t" after the common prefix and store it in a string named "repeatString"

  • Repeat the "repeatString" "l / m" times and append the result to the "result" string

Example

Following are the programs to the above Approach −

#include <stdio.h>
#include <string.h>

// Function to determine the greatest common divisor of two numbers
int gcd(int num1, int num2) {
   if (num2 == 0)
      return num1;
   return gcd(num2, num1 % num2);
}

// Function to compute the least common multiple of two numbers
int lcm(int num1, int num2) {
   return (num1 / gcd(num1, num2)) * num2;
}

void findSmallestString(char *s, char *t) {
   int n = strlen(s), m = strlen(t);
   int l = lcm(n, m);
   // Concatenate s and t to make st
   char st[n + m + 1];
   strcpy(st, s);
   strcat(st, t);
   // Initialize result string
   char result[n + m + 1];
   strcpy(result, "");
   // Add the common prefix of s and t to the result string
   for (int i = 0; i < (n < m ? n : m); i++) {
      if (s[i] != t[i]) {
         printf("-1\n");
         return;
      }
      strncat(result, &s[i], 1);
   }
   // If s and t are equal, output s
   if (n == m) {
      printf("%s\n", s);
      return;
   }
   // Swap s and t if n > m
   if (n > m) {
      int temp = n;
      n = m;
      m = temp;
      char *tempStr = s;
      s = t;
      t = tempStr;
   }
   // Repeat the remainder of t (after the common prefix) (l / m) times
   char repeatString[m - n + 1];
   strcpy(repeatString, &t[n]);
   for (int i = 0; i < l / m; i++) {
      strcat(result, repeatString);
   }
   printf("%s\n", result);
}
int main() {
   char S[] = "bcdbcd";
   char T[] = "bcd";
   printf("Minimum length string that is a multiple of the two given strings: ");
   findSmallestString(S, T);
   return 0;
}

Output

Minimum length string that is a multiple of the two given strings: bcdbcd
// C++ program to find the minimum length string that is a multiple of the two given strings
#include <iostream>
#include <string>
using namespace std;

// Function to determine the greatest common divisor of two numbers
int gcd(int num1, int num2) {
   if (num2 == 0)
   return num1;
   return gcd(num2, num1 % num2);
}
// Function to computer the least common multiple of two numbers
int lcm(int num1, int num2) {
   return (num1 / gcd(num1, num2)) * num2;
}
// Function to find the string of minimum length which is a multiple of strings s and t
void findSmallestString(string s, string t) {
   int n = s.length(), m = t.length();
   // Calculate LCM of n and m
   int l = lcm(n, m);
   // Concatenate s and t to make st
   string st = s + t;
   // Initialize result string
   string result = "";
   // Add the common prefix of s and t to the result string
   for (int i = 0; i < min(n, m); i++) {
      if (s[i] != t[i]) {
         cout << -1 << endl;
         return;
      }
      result += s[i];
   }
   // If s and t are equal, output s
   if (n == m) {
      cout << s << endl;
      return;
   }
   // Swap s and t if n > m
   if (n > m) {
      swap(n, m);
      swap(s, t);
   }
   // Repeat the remainder of t (after the common prefix) (l / m) times
   string repeatString = t.substr(n);
   for (int i = 0; i < l / m; i++) {
      result += repeatString;
   }
   // Print the resultant string
   cout << result << endl;
}
int main() {
   string S = "bcdbcd", T = "bcd";
   cout << "Minimum length string that is a multiple of the two given strings: "; 
   findSmallestString(S, T);
   return 0;
}

Output

Minimum length string that is a multiple of the two given strings: bcdbcd
public class SmallestMultipleString {
   // Function to determine the greatest common divisor of two numbers
   static int gcd(int num1, int num2) {
      if (num2 == 0)
         return num1;
      return gcd(num2, num1 % num2);
   }

   // Function to compute the least common multiple of two numbers
   static int lcm(int num1, int num2) {
      return (num1 / gcd(num1, num2)) * num2;
   }

   static void findSmallestString(String s, String t) {
      int n = s.length();
      int m = t.length();
      // Calculate LCM of n and m
      int l = lcm(n, m);
      // Concatenate s and t to make st
      String st = s + t;
      // Initialize result string
      StringBuilder result = new StringBuilder();
      // Add the common prefix of s and t to the result string
      for (int i = 0; i < Math.min(n, m); i++) {
         if (s.charAt(i) != t.charAt(i)) {
            System.out.println("-1");
            return;
         }
         result.append(s.charAt(i));
      }
      // If s and t are equal, output s
      if (n == m) {
         System.out.println(s);
         return;
      }
      // Swap s and t if n > m
      if (n > m) {
         int temp = n;
         n = m;
         m = temp;
         String tempStr = s;
         s = t;
         t = tempStr;
      }
      // Repeat the remainder of t (after the common prefix) (l / m) times
      String repeatString = t.substring(n);
      for (int i = 0; i < l / m; i++) {
         result.append(repeatString);
      }
      System.out.println(result);
   }

   public static void main(String[] args) {
      String S = "bcdbcd";
      String T = "bcd";
      System.out.print("Minimum length string that is a multiple of the two given strings: ");
      findSmallestString(S, T);
   }
}

Output

Minimum length string that is a multiple of the two given strings: bcdbcd
# Function to determine the greatest common divisor of two numbers
def gcd(num1, num2):
   if num2 == 0:
      return num1
   return gcd(num2, num1 % num2)

# Function to compute the least common multiple of two numbers
def lcm(num1, num2):
   return (num1 // gcd(num1, num2)) * num2

def find_smallest_string(s, t):
   n = len(s)
   m = len(t)
   # Calculate LCM of n and m
   l = lcm(n, m)
   # Concatenate s and t to make st
   st = s + t
   # Initialize result string
   result = ""
   # Add the common prefix of s and t to the result string
   for i in range(min(n, m)):
      if s[i] != t[i]:
         print("-1")
         return
      result += s[i]
   # If s and t are equal, output s
   if n == m:
      print(s)
      return
   # Swap s and t if n > m
   if n > m:
      n, m = m, n
      s, t = t, s
   # Repeat the remainder of t (after the common prefix) (l // m) times
   repeat_string = t[n:]
   for i in range(l // m):
      result += repeat_string
        
   print(result)

S = "bcdbcd"
T = "bcd"
print("Minimum length string that is a multiple of the two given strings:", end=" ")
find_smallest_string(S, T)

Output

Minimum length string that is a multiple of the two given strings: bcdbcd

Time Complexity − O(n*log n)

The time complexity of the program is determined by the lcm function, which has a time complexity of O(log n), where n is the length of the concatenated string formed by s and t. The program then iterates through the length of the result string, which can be up to n + m characters long. Additionally, the gcd function, which is called by the lcm function, also has a time complexity of O(log n). Overall, the time complexity of the program is dominated by the lcm function.

Space Complexity − O(n)

The space complexity of the program is O(n), where n represents the size of the concatenated string formed by combining s and t.This is because the program stores the concatenated string st, the result string, and the repeatString string, all of which can be up to n characters long. Additionally, the gcd and lcm functions require a constant amount of space, so their contribution to the overall space complexity is negligible. Overall, the space complexity of the program is dominated by the storage required for the strings.

Conclusion

The article discusses a naive approach as well an efficient approach to find the minimum length string that is a multiple of two given strings. The concept of the problem was explained through detailed examples. The solution approach was accompanied by pseudocode, various programs, and the time and space complex analysis.

Updated on: 27-Oct-2023

607 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements