Search code examples
javastringsubsequence

Code verifcation and optimization - Two String common substring


I was solving Two String problem. I have written below code. It passed 4 test cases but for two test cases it showed timeout. Kindly let me know how can I optimize it to avoid timeouts? Also any links which explains and shows examples of such optimization is welcome.

  public class TwoStrings
{
     private static final String YES = "YES";
private static final String NO  = "NO";

public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int testCases = Integer.parseInt(in.nextLine());
String input1[] = new String[testCases];
String input2[] = new String[testCases];

for (int i = 0; i < testCases; i++)
{
    input1[i] = in.nextLine();
    input2[i] = in.nextLine();
}
in.close();

for (int i = 0; i < testCases; i++)
{
    displayResult(input1[i], input2[i]);
}
}

private static void displayResult(String string1, String string2)
{
// choosing smaller String for iterating through it.
String smallerString = string1.length() <= string2.length() ? string1
    : string2;
String biggerString = string1 == smallerString ? string2 : string1;

boolean constains = false;

// Concept - Even if single letter is common, substring exists.
// So checking just one string.
for (int i = 0; i < smallerString.length(); i++)
{
    if (biggerString.contains(String.valueOf(smallerString.charAt(i))))
    {
    constains = true;
    break;
    }
}

if (constains)
    System.out.println(YES);
else
    System.out.println(NO);
}
}

Solution

  • What you are currently doing is O(n^2) because you loop through the small string and the search for that character in the longer string is a linear search because it is not sorted (all letters in alphabetical order).

    Below is a O(n) solution. The concept is to have a size 26 boolean array (one for each letter), and make an index true if a letter is in the small (could actually be small or long string, doesn't matter) string. Creating the array from the small string is O(n), and checking the letters in the long string is O(n), yielding a grand total of O(n + n), which reduces to O(n).

    private static void displayResult(String string1, String string2)
    {
        boolean[] contains = new boolean[26];
        boolean noSubstring = true;
    
        // populate the contains array
        for (char c : string1.toCharArray())
        {
            int value = (int)c - (int)'a';    // make the char 0-25
            contains[value] = true;
        }
    
        for (char c : string2.toCharArray())
        {
            int value = (int)c - (int)'a';    // make the char 0-25
    
            if (contains[value])
            {
                noSubstring = false;
                break;
            }
        }
    
        if (noSubstring)   System.out.println("NO");
        else               System.out.println("YES");
    }