Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.thealgorithms.slidingwindow;

/**
* The Subarrays with K Different Integers algorithm counts the number of subarrays
* that contain exactly k distinct integers.
*
* <p>
* Worst-case performance O(n)
* Best-case performance O(n)
* Average performance O(n)
* Worst-case space complexity O(k)
*
* @author https://github.com/Chiefpatwal
*/
public final class SubarraysWithKDifferentIntegers {

// Prevent instantiation
private SubarraysWithKDifferentIntegers() {
}

/**
* This method counts the number of subarrays with exactly k different integers.
*
* @param arr is the input array
* @param k is the number of distinct integers
* @return the count of subarrays with exactly k distinct integers
*/
public static int subarraysWithKDistinct(int[] arr, int k) {
return atMostKDistinct(arr, k) - atMostKDistinct(arr, k - 1);
}

// Helper method to count subarrays with at most k distinct integers
private static int atMostKDistinct(int[] arr, int k) {
if (k <= 0) {
return 0;
}

int count = 0; // To store the count of valid subarrays
int left = 0; // Left index of the sliding window
int[] frequency = new int[arr.length + 1]; // Frequency array to count distinct integers

for (int right = 0; right < arr.length; right++) {
if (frequency[arr[right]] == 0) {
k--; // New distinct integer added
}
frequency[arr[right]]++; // Increment the frequency of the current element

while (k < 0) { // More than k distinct integers
frequency[arr[left]]--; // Remove the leftmost element from the window
if (frequency[arr[left]] == 0) {
k++; // Distinct integer count reduced
}
left++; // Move the left index to the right
}
count += right - left + 1; // Count the number of valid subarrays ending at 'right'
}

return count; // Return the total count
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.thealgorithms.slidingwindow;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.Test;

/**
* Test cases for SubarraysWithKDifferentIntegers algorithm.
*
* <p>
* This class provides test cases to verify the correctness of the subarraysWithKDistinct
* method.
*
* @author https://github.com/Chiefpatwal
*/
public class SubarraysWithKDifferentIntegersTest {

@Test
public void testEdgeCases() {
// Test with an empty array
assertEquals(0, SubarraysWithKDifferentIntegers.subarraysWithKDistinct(new int[] {}, 1));

// Test with k greater than the number of distinct elements
assertEquals(0, SubarraysWithKDifferentIntegers.subarraysWithKDistinct(new int[] {1, 2, 3}, 5));

// Test with k = 0
assertEquals(0, SubarraysWithKDifferentIntegers.subarraysWithKDistinct(new int[] {1, 2, 3}, 0));

// Test with single element arrays
assertEquals(1, SubarraysWithKDifferentIntegers.subarraysWithKDistinct(new int[] {1}, 1));
assertEquals(0, SubarraysWithKDifferentIntegers.subarraysWithKDistinct(new int[] {1}, 2));

// Test case where all elements are the same
assertEquals(6, SubarraysWithKDifferentIntegers.subarraysWithKDistinct(new int[] {2, 2, 2}, 1)); // Corrected expected value
assertEquals(0, SubarraysWithKDifferentIntegers.subarraysWithKDistinct(new int[] {2, 2, 2}, 2)); // Not enough distinct elements
}
}