Welcome to Subscribe On Youtube
2730. Find the Longest Semi-Repetitive Substring
Description
You are given a 0-indexed string s that consists of digits from 0 to 9.
A string t is called a semi-repetitive if there is at most one consecutive pair of the same digits inside t. For example, 0010, 002020, 0123, 2002, and 54944 are semi-repetitive while 00101022, and 1101234883 are not.
Return the length of the longest semi-repetitive substring inside s.
A substring is a contiguous non-empty sequence of characters within a string.
Example 1:
Input: s = "52233" Output: 4 Explanation: The longest semi-repetitive substring is "5223", which starts at i = 0 and ends at j = 3.
Example 2:
Input: s = "5494" Output: 4 Explanation: s is a semi-reptitive string, so the answer is 4.
Example 3:
Input: s = "1111111" Output: 2 Explanation: The longest semi-repetitive substring is "11", which starts at i = 0 and ends at j = 1.
Constraints:
1 <= s.length <= 50'0' <= s[i] <= '9'
Solutions
Solution 1: Two Pointers
We use two pointers to maintain a range $s[j..i]$ such that there is at most one pair of adjacent characters that are equal, initially $j = 0$, $i = 1$. Initialize the answer $ans = 1$.
We use $cnt$ to record the number of pairs of adjacent characters that are equal in the range. If $cnt > 1$, then we need to move the left pointer $j$ until $cnt \le 1$. Each time, we update the answer as $ans = \max(ans, i - j + 1)$.
The time complexity is $O(n)$, where $n$ is the length of the string. The space complexity is $O(1)$.
Solution 2: Two Pointers (Optimization)
Since the problem only requires us to find the length of the longest semi-repetitive substring, each time the number of adjacent identical characters in the interval exceeds $1$, we can move the left pointer $l$ once, while the right pointer $r$ continues to move to the right. This ensures that the length of the substring does not decrease.
Finally, the answer is $n - l$, where $n$ is the length of the string.
The time complexity is $O(n)$, where $n$ is the length of the string. The space complexity is $O(1)$.
-
class Solution { public int longestSemiRepetitiveSubstring(String s) { int n = s.length(); int ans = 0; for (int i = 0, j = 0, cnt = 0; i < n; ++i) { if (i > 0 && s.charAt(i) == s.charAt(i - 1)) { ++cnt; } while (cnt > 1) { if (s.charAt(j) == s.charAt(j + 1)) { --cnt; } ++j; } ans = Math.max(ans, i - j + 1); } return ans; } } // Solution 2 class Solution { public int longestSemiRepetitiveSubstring(String s) { int n = s.length(); int cnt = 0, l = 0; for (int i = 1; i < n; ++i) { cnt += s.charAt(i) == s.charAt(i - 1) ? 1 : 0; if (cnt > 1) { cnt -= s.charAt(l) == s.charAt(++l) ? 1 : 0; } } return n - l; } } -
class Solution { public: int longestSemiRepetitiveSubstring(string s) { int n = s.size(); int ans = 0; for (int i = 0, j = 0, cnt = 0; i < n; ++i) { if (i && s[i] == s[i - 1]) { ++cnt; } while (cnt > 1) { if (s[j] == s[j + 1]) { --cnt; } ++j; } ans = max(ans, i - j + 1); } return ans; } }; // Solution 2 class Solution { public: int longestSemiRepetitiveSubstring(string s) { int n = s.length(); int cnt = 0, l = 0; for (int i = 1; i < n; ++i) { cnt += s[i] == s[i - 1] ? 1 : 0; if (cnt > 1) { cnt -= s[l] == s[++l] ? 1 : 0; } } return n - l; } }; -
class Solution: def longestSemiRepetitiveSubstring(self, s: str) -> int: n = len(s) ans = cnt = j = 0 for i in range(n): if i and s[i] == s[i - 1]: cnt += 1 while cnt > 1: if s[j] == s[j + 1]: cnt -= 1 j += 1 ans = max(ans, i - j + 1) return ans # Solution 2 class Solution: def longestSemiRepetitiveSubstring(self, s: str) -> int: n = len(s) cnt = l = 0 for i in range(1, n): cnt += s[i] == s[i - 1] if cnt > 1: cnt -= s[l] == s[l + 1] l += 1 return n - l -
func longestSemiRepetitiveSubstring(s string) (ans int) { n := len(s) for i, j, cnt := 0, 0, 0; i < n; i++ { if i > 0 && s[i] == s[i-1] { cnt++ } for cnt > 1 { if s[j] == s[j+1] { cnt-- } j++ } ans = max(ans, i-j+1) } return } // Solution 2 func longestSemiRepetitiveSubstring(s string) (ans int) { cnt, l := 0, 0 for i, c := range s[1:] { if byte(c) == s[i] { cnt++ } if cnt > 1 { if s[l] == s[l+1] { cnt-- } l++ } } return len(s) - l } -
function longestSemiRepetitiveSubstring(s: string): number { const n = s.length; let ans = 0; for (let i = 0, j = 0, cnt = 0; i < n; ++i) { if (i > 0 && s[i] === s[i - 1]) { ++cnt; } while (cnt > 1) { if (s[j] === s[j + 1]) { --cnt; } ++j; } ans = Math.max(ans, i - j + 1); } return ans; } // Solution 2 function longestSemiRepetitiveSubstring(s: string): number { const n = s.length; let [cnt, l] = [0, 0]; for (let i = 1; i < n; ++i) { cnt += s[i] === s[i - 1] ? 1 : 0; if (cnt > 1) { cnt -= s[l] === s[l + 1] ? 1 : 0; ++l; } } return n - l; }