diff --git a/algorithms-and-data-structures/src/main/java/com/xtenzq/arrays/SlidingWindow.java b/algorithms-and-data-structures/src/main/java/com/xtenzq/arrays/SlidingWindow.java index 196c113..9db0459 100644 --- a/algorithms-and-data-structures/src/main/java/com/xtenzq/arrays/SlidingWindow.java +++ b/algorithms-and-data-structures/src/main/java/com/xtenzq/arrays/SlidingWindow.java @@ -23,4 +23,31 @@ public static int findLongestSubArraySumLessOrEqualK(int[] nums, int k) { } return answer; } + + /** + * Finds the length of the longest substring of "1"s in a binary string after flipping at most one "0" to "1". + * + * @param s the binary string consisting of '0' and '1' + * @return the length of the longest substring achievable that contains only '1's after flipping at most one '0' + * @implNote This method runs in {@code O(n)} time complexity and {@code O(1)} space complexity, + * where {@code n} is the length of {@code s}. + */ + public static int findLongestSubstringAfterOneFlip(String s) { + int left = 0, answer = 0, zeroCounter = 0; + for (int right = 0; right < s.length(); right++) { + if (s.charAt(right) == '0') { + zeroCounter++; + } + + while (zeroCounter > 1) { + if (s.charAt(left) == '0') { + zeroCounter--; + } + left++; + } + + answer = Math.max(answer, right - left + 1); + } + return answer; + } } diff --git a/algorithms-and-data-structures/src/test/java/com/xtenzq/arrays/SlidingWindowTest.java b/algorithms-and-data-structures/src/test/java/com/xtenzq/arrays/SlidingWindowTest.java index dfb9c89..9ba2fa8 100644 --- a/algorithms-and-data-structures/src/test/java/com/xtenzq/arrays/SlidingWindowTest.java +++ b/algorithms-and-data-structures/src/test/java/com/xtenzq/arrays/SlidingWindowTest.java @@ -2,8 +2,9 @@ import org.junit.jupiter.api.Test; +import static com.xtenzq.arrays.SlidingWindow.findLongestSubstringAfterOneFlip; import static com.xtenzq.arrays.SlidingWindow.findLongestSubArraySumLessOrEqualK; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; class SlidingWindowTest { @@ -48,4 +49,58 @@ void testFindLongestSubArraySumLessOrEqualK_EmptyArray() { int k = 5; assertEquals(0, findLongestSubArraySumLessOrEqualK(nums, k)); } + + @Test + void testFindLongestSubstringAfterOneFlip_Example1() { + String s = "1101100111"; + assertEquals(5, findLongestSubstringAfterOneFlip(s)); + } + + @Test + void testFindLongestSubstringAfterOneFlip_AllOnes() { + String s = "1111111"; + assertEquals(7, findLongestSubstringAfterOneFlip(s)); + } + + @Test + void testFindLongestSubstringAfterOneFlip_AllZeros() { + String s = "00000"; + assertEquals(1, findLongestSubstringAfterOneFlip(s)); + } + + @Test + void testFindLongestSubstringAfterOneFlip_SingleZero() { + String s = "1"; + assertEquals(1, findLongestSubstringAfterOneFlip(s)); + } + + @Test + void testFindLongestOneBinaryString_SingleSubstringAfterOne() { + String s = "0"; + assertEquals(1, findLongestSubstringAfterOneFlip(s)); + } + + @Test + void testFindLongestSubstringAfterOneFlip_AlternateOnesAndZeros() { + String s = "1010101010"; + assertEquals(3, findLongestSubstringAfterOneFlip(s)); + } + + @Test + void testFindLongestSubstringAfterOneFlip_LeadingZeros() { + String s = "000011110000"; + assertEquals(5, findLongestSubstringAfterOneFlip(s)); + } + + @Test + void testFindLongestSubstringAfterOneFlip_TrailingZeros() { + String s = "11110000"; + assertEquals(5, findLongestSubstringAfterOneFlip(s)); + } + + @Test + void testFindLongestSubstringAfterOneFlip_ComplexPattern() { + String s = "100110111001111"; + assertEquals(6, findLongestSubstringAfterOneFlip(s)); + } } \ No newline at end of file