Welcome to Subscribe On Youtube
1638. Count Substrings That Differ by One Character
Description
Given two strings s and t, find the number of ways you can choose a non-empty substring of s and replace a single character by a different character such that the resulting substring is a substring of t. In other words, find the number of substrings in s that differ from some substring in t by exactly one character.
For example, the underlined substrings in "computer" and "computation" only differ by the 'e'/'a', so this is a valid way.
Return the number of substrings that satisfy the condition above.
A substring is a contiguous sequence of characters within a string.
Example 1:
Input: s = "aba", t = "baba"
Output: 6
Explanation: The following are the pairs of substrings from s and t that differ by exactly 1 character:
("aba", "baba")
("aba", "baba")
("aba", "baba")
("aba", "baba")
("aba", "baba")
("aba", "baba")
The underlined portions are the substrings that are chosen from s and t.
Example 2:
Input: s = "ab", t = "bb"
Output: 3
Explanation: The following are the pairs of substrings from s and t that differ by 1 character:
("ab", "bb")
("ab", "bb")
("ab", "bb")
The underlined portions are the substrings that are chosen from s and t.
Constraints:
1 <= s.length, t.length <= 100sandtconsist of lowercase English letters only.
Solutions
Solution 1: Sliding Window
We can enumerate the different character positions in the strings $s$ and $t$, and then expand to both sides until different characters are encountered, so that we can get the number of substring pairs that meet the conditions centered on this position. We record the number of identical characters extended on the left as $l$, and the number of identical characters extended on the right as $r$. Then the number of substring pairs that meet the conditions centered at this position is $(l + 1) \times (r + 1)$, which can be added to the answer.
After the enumeration is completed, the answer can be obtained.
Time complexity $O(m \times n \times \min(m, n))$, space complexity $O(1)$. Where $m$ and $n$ are the lengths of the strings $s$ and $t$ respectively.
Solution 2
In method one, we need to expand to the left and right sides each time to get the values of $l$ and $r$. In fact, we can preprocess out the length of the longest identical suffix ending at each position $(i, j)$, and the length of the longest identical prefix starting at each position $(i, j)$, recorded in the arrays $f$ and $g$ respectively.
Next, similar to method 1, we enumerate the different character positions $(i, j)$ in the strings $s$ and $t$. Then the number of substring pairs that meet the condition centered on this position is $(f[i][j] + 1) \times (g[i + 1][j + 1] + 1)$, which can be added to the answer.
Time complexity $O(m \times n)$, space complexity $O(m \times n)$. Where $m$ and $n$ are the lengths of the strings $s$ and $t$ respectively.
-
class Solution { public int countSubstrings(String s, String t) { int ans = 0; int m = s.length(), n = t.length(); for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { if (s.charAt(i) != t.charAt(j)) { int l = 0, r = 0; while (i - l > 0 && j - l > 0 && s.charAt(i - l - 1) == t.charAt(j - l - 1)) { ++l; } while (i + r + 1 < m && j + r + 1 < n && s.charAt(i + r + 1) == t.charAt(j + r + 1)) { ++r; } ans += (l + 1) * (r + 1); } } } return ans; } } // Solution 2 class Solution { public int countSubstrings(String s, String t) { int ans = 0; int m = s.length(), n = t.length(); int[][] f = new int[m + 1][n + 1]; int[][] g = new int[m + 1][n + 1]; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { if (s.charAt(i) == t.charAt(j)) { f[i + 1][j + 1] = f[i][j] + 1; } } } for (int i = m - 1; i >= 0; --i) { for (int j = n - 1; j >= 0; --j) { if (s.charAt(i) == t.charAt(j)) { g[i][j] = g[i + 1][j + 1] + 1; } else { ans += (f[i][j] + 1) * (g[i + 1][j + 1] + 1); } } } return ans; } } -
class Solution { public: int countSubstrings(string s, string t) { int ans = 0; int m = s.size(), n = t.size(); for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { if (s[i] != t[j]) { int l = 0, r = 0; while (i - l > 0 && j - l > 0 && s[i - l - 1] == t[j - l - 1]) { ++l; } while (i + r + 1 < m && j + r + 1 < n && s[i + r + 1] == t[j + r + 1]) { ++r; } ans += (l + 1) * (r + 1); } } } return ans; } }; // Solution 2 class Solution { public: int countSubstrings(string s, string t) { int ans = 0; int m = s.length(), n = t.length(); int f[m + 1][n + 1]; int g[m + 1][n + 1]; memset(f, 0, sizeof(f)); memset(g, 0, sizeof(g)); for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { if (s[i] == t[j]) { f[i + 1][j + 1] = f[i][j] + 1; } } } for (int i = m - 1; i >= 0; --i) { for (int j = n - 1; j >= 0; --j) { if (s[i] == t[j]) { g[i][j] = g[i + 1][j + 1] + 1; } else { ans += (f[i][j] + 1) * (g[i + 1][j + 1] + 1); } } } return ans; } }; -
class Solution: def countSubstrings(self, s: str, t: str) -> int: ans = 0 m, n = len(s), len(t) for i, a in enumerate(s): for j, b in enumerate(t): if a != b: l = r = 0 while i > l and j > l and s[i - l - 1] == t[j - l - 1]: l += 1 while ( i + r + 1 < m and j + r + 1 < n and s[i + r + 1] == t[j + r + 1] ): r += 1 ans += (l + 1) * (r + 1) return ans # Solution 2 class Solution: def countSubstrings(self, s: str, t: str) -> int: ans = 0 m, n = len(s), len(t) f = [[0] * (n + 1) for _ in range(m + 1)] g = [[0] * (n + 1) for _ in range(m + 1)] for i, a in enumerate(s, 1): for j, b in enumerate(t, 1): if a == b: f[i][j] = f[i - 1][j - 1] + 1 for i in range(m - 1, -1, -1): for j in range(n - 1, -1, -1): if s[i] == t[j]: g[i][j] = g[i + 1][j + 1] + 1 else: ans += (f[i][j] + 1) * (g[i + 1][j + 1] + 1) return ans -
func countSubstrings(s string, t string) (ans int) { m, n := len(s), len(t) for i, a := range s { for j, b := range t { if a != b { l, r := 0, 0 for i > l && j > l && s[i-l-1] == t[j-l-1] { l++ } for i+r+1 < m && j+r+1 < n && s[i+r+1] == t[j+r+1] { r++ } ans += (l + 1) * (r + 1) } } } return } // Solution 2 func countSubstrings(s string, t string) (ans int) { m, n := len(s), len(t) f := make([][]int, m+1) g := make([][]int, m+1) for i := range f { f[i] = make([]int, n+1) g[i] = make([]int, n+1) } for i, a := range s { for j, b := range t { if a == b { f[i+1][j+1] = f[i][j] + 1 } } } for i := m - 1; i >= 0; i-- { for j := n - 1; j >= 0; j-- { if s[i] == t[j] { g[i][j] = g[i+1][j+1] + 1 } else { ans += (f[i][j] + 1) * (g[i+1][j+1] + 1) } } } return }