diff --git a/src/main/java/com/thealgorithms/slidingwindow/LongestSubstringWithoutRepeatingCharacters.java b/src/main/java/com/thealgorithms/slidingwindow/LongestSubstringWithoutRepeatingCharacters.java new file mode 100644 index 000000000000..0641730d8b09 --- /dev/null +++ b/src/main/java/com/thealgorithms/slidingwindow/LongestSubstringWithoutRepeatingCharacters.java @@ -0,0 +1,46 @@ +package com.thealgorithms.slidingwindow; +import java.util.HashSet; + +/** + * The Longest Substring Without Repeating Characters algorithm finds the length of + * the longest substring without repeating characters in a given string. + * + *

+ * Worst-case performance O(n) + * Best-case performance O(n) + * Average performance O(n) + * Worst-case space complexity O(min(n, m)), where n is the length of the string + * and m is the size of the character set. + * + * @author (https://github.com/Chiefpatwal) + */ +public final class LongestSubstringWithoutRepeatingCharacters { + + // Prevent instantiation + private LongestSubstringWithoutRepeatingCharacters() { + } + + /** + * This method finds the length of the longest substring without repeating characters. + * + * @param s is the input string + * @return the length of the longest substring without repeating characters + */ + public static int lengthOfLongestSubstring(String s) { + int maxLength = 0; + int left = 0; + HashSet charSet = new HashSet<>(); + + for (int right = 0; right < s.length(); right++) { + // If the character is already in the set, remove characters from the left + while (charSet.contains(s.charAt(right))) { + charSet.remove(s.charAt(left)); + left++; + } + charSet.add(s.charAt(right)); + maxLength = Math.max(maxLength, right - left + 1); + } + + return maxLength; + } +} diff --git a/src/main/java/com/thealgorithms/slidingwindow/MaxSumKSizeSubarray.java b/src/main/java/com/thealgorithms/slidingwindow/MaxSumKSizeSubarray.java new file mode 100644 index 000000000000..7e8095e08a0b --- /dev/null +++ b/src/main/java/com/thealgorithms/slidingwindow/MaxSumKSizeSubarray.java @@ -0,0 +1,50 @@ +package com.thealgorithms.slidingwindow; + +/** + * The Sliding Window algorithm is used to find the maximum sum of a subarray + * of a fixed size k within a given array. + * + *

+ * Worst-case performance O(n) + * Best-case performance O(n) + * Average performance O(n) + * Worst-case space complexity O(1) + * + * @author Your Name (https://github.com/Chiefpatwal) + */ +public final class MaxSumKSizeSubarray { + + // Prevent instantiation + private MaxSumKSizeSubarray() { + } + + /** + * This method finds the maximum sum of a subarray of a given size k. + * + * @param arr is the input array where the maximum sum needs to be found + * @param k is the size of the subarray + * @return the maximum sum of the subarray of size k + */ + public static int maxSumKSizeSubarray(int[] arr, int k) { + if (arr.length < k) { + return -1; // Edge case: not enough elements + } + + int maxSum; + int windowSum = 0; + + // Calculate the sum of the first window + for (int i = 0; i < k; i++) { + windowSum += arr[i]; + } + maxSum = windowSum; + + // Slide the window across the array + for (int i = k; i < arr.length; i++) { + windowSum += arr[i] - arr[i - k]; + maxSum = Math.max(maxSum, windowSum); + } + + return maxSum; + } +} diff --git a/src/main/java/com/thealgorithms/slidingwindow/MinimumConsecutiveCards.java b/src/main/java/com/thealgorithms/slidingwindow/MinimumConsecutiveCards.java new file mode 100644 index 000000000000..02bcc396bcb9 --- /dev/null +++ b/src/main/java/com/thealgorithms/slidingwindow/MinimumConsecutiveCards.java @@ -0,0 +1,44 @@ +package com.thealgorithms.slidingwindow; + +import java.util.HashMap; + +/** + * The MinimumConsecutiveCards algorithm finds the minimum number of consecutive cards + * that need to be picked up to get a pair of the same card. + * + *

+ * Worst-case performance O(n) + * Best-case performance O(n) + * Average performance O(n) + * Worst-case space complexity O(n) + * + * @author (https://github.com/Chiefpatwal) + */ +public final class MinimumConsecutiveCards { + + // Prevent instantiation + private MinimumConsecutiveCards() { + } + + /** + * This method finds the minimum number of consecutive cards needed to be picked up + * to get a pair of the same card. + * + * @param cards an array of integers representing card numbers + * @return the minimum number of consecutive cards to pick up, or -1 if no pairs exist + */ + public static int minimumCardPickup(int[] cards) { + HashMap cardIndexMap = new HashMap<>(); + int minLength = Integer.MAX_VALUE; + + for (int i = 0; i < cards.length; i++) { + if (cardIndexMap.containsKey(cards[i])) { + int prevIndex = cardIndexMap.get(cards[i]); + minLength = Math.min(minLength, i - prevIndex + 1); + } + cardIndexMap.put(cards[i], i); + } + + return minLength == Integer.MAX_VALUE ? -1 : minLength; + } +} diff --git a/src/test/java/com/thealgorithms/slidingwindow/LongestSubstringWithoutRepeatingCharactersTest.java b/src/test/java/com/thealgorithms/slidingwindow/LongestSubstringWithoutRepeatingCharactersTest.java new file mode 100644 index 000000000000..8638a707a3e2 --- /dev/null +++ b/src/test/java/com/thealgorithms/slidingwindow/LongestSubstringWithoutRepeatingCharactersTest.java @@ -0,0 +1,23 @@ +package com.thealgorithms.slidingwindow; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +/** + * Unit tests for the LongestSubstringWithoutRepeatingCharacters class. + * + * @author (https://github.com/Chiefpatwal) + */ +public class LongestSubstringWithoutRepeatingCharactersTest { + + @Test + public void testLengthOfLongestSubstring() { + // Test cases for the lengthOfLongestSubstring method + assertEquals(3, LongestSubstringWithoutRepeatingCharacters.lengthOfLongestSubstring("abcabcbb")); + assertEquals(1, LongestSubstringWithoutRepeatingCharacters.lengthOfLongestSubstring("bbbbb")); + assertEquals(3, LongestSubstringWithoutRepeatingCharacters.lengthOfLongestSubstring("pwwkew")); + assertEquals(0, LongestSubstringWithoutRepeatingCharacters.lengthOfLongestSubstring("")); + assertEquals(5, LongestSubstringWithoutRepeatingCharacters.lengthOfLongestSubstring("abcde")); + } +} diff --git a/src/test/java/com/thealgorithms/slidingwindow/MaxSumKSizeSubarrayTest.java b/src/test/java/com/thealgorithms/slidingwindow/MaxSumKSizeSubarrayTest.java new file mode 100644 index 000000000000..aa3c2eae3294 --- /dev/null +++ b/src/test/java/com/thealgorithms/slidingwindow/MaxSumKSizeSubarrayTest.java @@ -0,0 +1,79 @@ +package com.thealgorithms.slidingwindow; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +/** + * Unit tests for the MaxSumKSizeSubarray class. + * + * @author Your Name (https://github.com/Chiefpatwal) + */ +class MaxSumKSizeSubarrayTest { + + /** + * Test for the basic case of finding the maximum sum. + */ + @Test + void testMaxSumKSizeSubarray() { + int[] arr = {1, 2, 3, 4, 5}; + int k = 2; + int expectedMaxSum = 9; // 4 + 5 + assertEquals(expectedMaxSum, MaxSumKSizeSubarray.maxSumKSizeSubarray(arr, k)); + } + + /** + * Test for a different array and subarray size. + */ + @Test + void testMaxSumKSizeSubarrayWithDifferentValues() { + int[] arr = {2, 1, 5, 1, 3, 2}; + int k = 3; + int expectedMaxSum = 9; // 5 + 1 + 3 + assertEquals(expectedMaxSum, MaxSumKSizeSubarray.maxSumKSizeSubarray(arr, k)); + } + + /** + * Test for edge case with insufficient elements. + */ + @Test + void testMaxSumKSizeSubarrayWithInsufficientElements() { + int[] arr = {1, 2}; + int k = 3; // Not enough elements + int expectedMaxSum = -1; // Edge case + assertEquals(expectedMaxSum, MaxSumKSizeSubarray.maxSumKSizeSubarray(arr, k)); + } + + /** + * Test for large array. + */ + @Test + void testMaxSumKSizeSubarrayWithLargeArray() { + int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + int k = 5; + int expectedMaxSum = 40; // 6 + 7 + 8 + 9 + 10 + assertEquals(expectedMaxSum, MaxSumKSizeSubarray.maxSumKSizeSubarray(arr, k)); + } + + /** + * Test for array with negative numbers. + */ + @Test + void testMaxSumKSizeSubarrayWithNegativeNumbers() { + int[] arr = {-1, -2, -3, -4, -5}; + int k = 2; + int expectedMaxSum = -3; // -1 + -2 + assertEquals(expectedMaxSum, MaxSumKSizeSubarray.maxSumKSizeSubarray(arr, k)); + } + + /** + * Test for the case where k equals the array length. + */ + @Test + void testMaxSumKSizeSubarrayWithKEqualToArrayLength() { + int[] arr = {1, 2, 3, 4, 5}; + int k = 5; + int expectedMaxSum = 15; // 1 + 2 + 3 + 4 + 5 + assertEquals(expectedMaxSum, MaxSumKSizeSubarray.maxSumKSizeSubarray(arr, k)); + } +} diff --git a/src/test/java/com/thealgorithms/slidingwindow/MinimumConsecutiveCardsTest.java b/src/test/java/com/thealgorithms/slidingwindow/MinimumConsecutiveCardsTest.java new file mode 100644 index 000000000000..e00bf91ee1f9 --- /dev/null +++ b/src/test/java/com/thealgorithms/slidingwindow/MinimumConsecutiveCardsTest.java @@ -0,0 +1,22 @@ +package com.thealgorithms.slidingwindow; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +/** + * Unit tests for the MinimumConsecutiveCards class. + * + * @author (https://github.com/Chiefpatwal) + */ +public class MinimumConsecutiveCardsTest { + + @Test + public void testMinimumCardPickup() { + // Test cases for the minimumCardPickup method + assertEquals(2, MinimumConsecutiveCards.minimumCardPickup(new int[] {1, 2, 3, 2, 4, 1})); + assertEquals(-1, MinimumConsecutiveCards.minimumCardPickup(new int[] {1, 2, 3, 4, 5})); + assertEquals(2, MinimumConsecutiveCards.minimumCardPickup(new int[] {1, 1, 1, 1})); + assertEquals(2, MinimumConsecutiveCards.minimumCardPickup(new int[] {2, 2, 3, 4, 5})); + } +}