From ca00cadb354859734dd18649b5ef7912e8967002 Mon Sep 17 00:00:00 2001 From: alxkm Date: Tue, 27 Aug 2024 23:47:00 +0200 Subject: [PATCH 1/2] refactor: LongestNonRepetitiveSubstring --- .../LongestNonRepetitiveSubstring.java | 59 ++++++++----------- .../LongestNonRepetitiveSubstringTest.java | 23 +++++--- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/main/java/com/thealgorithms/strings/LongestNonRepetitiveSubstring.java b/src/main/java/com/thealgorithms/strings/LongestNonRepetitiveSubstring.java index c113162ff435..6808cd50602f 100644 --- a/src/main/java/com/thealgorithms/strings/LongestNonRepetitiveSubstring.java +++ b/src/main/java/com/thealgorithms/strings/LongestNonRepetitiveSubstring.java @@ -3,47 +3,40 @@ import java.util.HashMap; import java.util.Map; +/** + * Class for finding the length of the longest substring without repeating characters. + */ final class LongestNonRepetitiveSubstring { private LongestNonRepetitiveSubstring() { } + /** + * Finds the length of the longest substring without repeating characters. + * + * @param s the input string + * @return the length of the longest non-repetitive substring + */ public static int lengthOfLongestSubstring(String s) { - int max = 0; + int maxLength = 0; int start = 0; - int i = 0; - Map map = new HashMap<>(); - - while (i < s.length()) { - char temp = s.charAt(i); - - // adding key to map if not present - if (!map.containsKey(temp)) { - map.put(temp, 0); - } else if (s.charAt(start) == temp) { - start++; - } else if (s.charAt(i - 1) == temp) { - if (max < map.size()) { - max = map.size(); - } - map = new HashMap<>(); - start = i; - i--; - } else { - if (max < map.size()) { - max = map.size(); - } - while (s.charAt(start) != temp) { - map.remove(s.charAt(start)); - start++; - } - start++; + Map charIndexMap = new HashMap<>(); + + for (int i = 0; i < s.length(); i++) { + char currentChar = s.charAt(i); + + // If the character is already in the map and its index is within the current window + if (charIndexMap.containsKey(currentChar) && charIndexMap.get(currentChar) >= start) { + // Move the start to the position right after the last occurrence of the current character + start = charIndexMap.get(currentChar) + 1; } - i++; - } - if (max < map.size()) { - max = map.size(); + // Update the last seen index of the current character + charIndexMap.put(currentChar, i); + + // Calculate the maximum length of the substring without repeating characters + maxLength = Math.max(maxLength, i - start + 1); } - return max; + + return maxLength; } } diff --git a/src/test/java/com/thealgorithms/strings/LongestNonRepetitiveSubstringTest.java b/src/test/java/com/thealgorithms/strings/LongestNonRepetitiveSubstringTest.java index c6fd8c59c53e..2d6db6b13e96 100644 --- a/src/test/java/com/thealgorithms/strings/LongestNonRepetitiveSubstringTest.java +++ b/src/test/java/com/thealgorithms/strings/LongestNonRepetitiveSubstringTest.java @@ -1,15 +1,22 @@ package com.thealgorithms.strings; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; public class LongestNonRepetitiveSubstringTest { - @Test - public void palindrome() { - String input1 = "HelloWorld"; - String input2 = "javaIsAProgrammingLanguage"; - Assertions.assertEquals(LongestNonRepetitiveSubstring.lengthOfLongestSubstring(input1), 5); - Assertions.assertEquals(LongestNonRepetitiveSubstring.lengthOfLongestSubstring(input2), 9); + private static Stream provideTestCases() { + return Stream.of(Arguments.of("", 0), Arguments.of("a", 1), Arguments.of("abcde", 5), Arguments.of("aaaaa", 1), Arguments.of("abca", 3), Arguments.of("abcdeabc", 5), + Arguments.of("a1b2c3", 6), Arguments.of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", 62), Arguments.of("aabb", 2), Arguments.of("abcdefghijabc", 10)); + } + + @ParameterizedTest + @MethodSource("provideTestCases") + void testLengthOfLongestSubstring(String input, int expectedLength) { + assertEquals(expectedLength, LongestNonRepetitiveSubstring.lengthOfLongestSubstring(input)); } } From a2ca118400048e0443a09bb56907ac78ba7dc62b Mon Sep 17 00:00:00 2001 From: alxkm Date: Tue, 27 Aug 2024 23:49:22 +0200 Subject: [PATCH 2/2] checkstyle: fix formatting --- .../strings/LongestNonRepetitiveSubstringTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/thealgorithms/strings/LongestNonRepetitiveSubstringTest.java b/src/test/java/com/thealgorithms/strings/LongestNonRepetitiveSubstringTest.java index 2d6db6b13e96..791c4ba3ae32 100644 --- a/src/test/java/com/thealgorithms/strings/LongestNonRepetitiveSubstringTest.java +++ b/src/test/java/com/thealgorithms/strings/LongestNonRepetitiveSubstringTest.java @@ -10,8 +10,8 @@ public class LongestNonRepetitiveSubstringTest { private static Stream provideTestCases() { - return Stream.of(Arguments.of("", 0), Arguments.of("a", 1), Arguments.of("abcde", 5), Arguments.of("aaaaa", 1), Arguments.of("abca", 3), Arguments.of("abcdeabc", 5), - Arguments.of("a1b2c3", 6), Arguments.of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", 62), Arguments.of("aabb", 2), Arguments.of("abcdefghijabc", 10)); + return Stream.of(Arguments.of("", 0), Arguments.of("a", 1), Arguments.of("abcde", 5), Arguments.of("aaaaa", 1), Arguments.of("abca", 3), Arguments.of("abcdeabc", 5), Arguments.of("a1b2c3", 6), Arguments.of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", 62), + Arguments.of("aabb", 2), Arguments.of("abcdefghijabc", 10)); } @ParameterizedTest