Memoization III: remembering the bad paths

This problem was very interesting, I tried it without memoization and it ran into TLE (Time Limit Exceeded), adding memoization for the bad paths solved it. Let's see.


97. Interleaving String
Medium

Given strings s1s2, and s3, find whether s3 is formed by an interleaving of s1 and s2.

An interleaving of two strings s and t is a configuration where they are divided into non-empty substrings such that:

  • s = s1 + s2 + ... + sn
  • t = t1 + t2 + ... + tm
  • |n - m| <= 1
  • The interleaving is s1 + t1 + s2 + t2 + s3 + t3 + ... or t1 + s1 + t2 + s2 + t3 + s3 + ...

Note: a + b is the concatenation of strings a and b.

 

Example 1:

Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
Output: true

Example 2:

Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
Output: false

Example 3:

Input: s1 = "", s2 = "", s3 = ""
Output: true

 

Constraints:

  • 0 <= s1.length, s2.length <= 100
  • 0 <= s3.length <= 200
  • s1s2, and s3 consist of lowercase English letters.

My first implementation (simple DFS with backtracking) failed in the last two test cases with TLE. Here was my first implementation:

public class Solution {
    public bool IsInterleave(string s1, string s2, string s3)
    {
        if (s1.Length + s2.Length != s3.Length) return false;
        return IsInterleave(s1, 0, s2, 0, s3, 0);
    }

    public bool IsInterleave(string s1,
                             int i1,
                             string s2,
                             int i2,
                             string s3,
                             int i3)
    {
        if (i1 >= s1.Length && i2 >= s2.Length && i3 >= s3.Length) return true;
        if (i3 >= s3.Length) return false;
        if (i1 < s1.Length && s1[i1] == s3[i3] && IsInterleave(s1, i1 + 1, s2, i2, s3, i3 + 1)) return true;
        if (i2 < s2.Length && s2[i2] == s3[i3] && IsInterleave(s1, i1, s2, i2 + 1, s3, i3 + 1)) return true;
        return false;
    }
}

The solution was simple: add a hash table keeping track of the combinations of (i1, i2, i3) that led to a false outcome. We need to get a unique key for the 3-tuple (i1, i2, i3), I like to use some simple math using the constraints of each one of the indexes to come up with a unique number. It did the trick. New code is down below, cheers, ACC.

public class Solution {
    public bool IsInterleave(string s1, string s2, string s3)
    {
        if (s1.Length + s2.Length != s3.Length) return false;
        return IsInterleave(s1, 0, s2, 0, s3, 0, new Hashtable());
    }

    public bool IsInterleave(string s1,
                             int i1,
                             string s2,
                             int i2,
                             string s3,
                             int i3,
                             Hashtable memo)
    {
        if (i1 >= s1.Length && i2 >= s2.Length && i3 >= s3.Length) return true;
        if (i3 >= s3.Length) return false;

        int key = (i1 + 1) + (i2 + 1) * 105 + (i3 + 1) * 1005;
        if (memo.ContainsKey(key)) return false;

        if (i1 < s1.Length && s1[i1] == s3[i3] && IsInterleave(s1, i1 + 1, s2, i2, s3, i3 + 1, memo)) return true;
        if (i2 < s2.Length && s2[i2] == s3[i3] && IsInterleave(s1, i1, s2, i2 + 1, s3, i3 + 1, memo)) return true;

        if (!memo.ContainsKey(key)) memo.Add(key, false);
        return false;
    }
}


Comments

  1. Casino near Harrah's Cherokee - Mapyro
    Harrah's Cherokee Casino Resort in 경기도 출장마사지 Cherokee, 고양 출장샵 North Carolina offers casino gaming, hotel rooms, restaurants, entertainment and more. 경상남도 출장안마 It 아산 출장안마 also 파주 출장마사지 has over 2,600

    ReplyDelete

Post a Comment

Popular posts from this blog

Changing the root of a binary tree

ProjectEuler Problem 719 (some hints, but no spoilers)

The Power Sum, a recursive problem by HackerRank