diff --git a/Sliding Window Problems/duplicates_within_given_range_k_in_array.cpp b/Sliding Window Problems/duplicates_within_given_range_k_in_array.cpp new file mode 100644 index 0000000..cea5497 --- /dev/null +++ b/Sliding Window Problems/duplicates_within_given_range_k_in_array.cpp @@ -0,0 +1,73 @@ +/* +Problem: +Given an array and a positive number k, +check whether the array contains any duplicate elements within range k. +If k is more than size of the array, the solution should check for duplicates in the complete array + +Using Sliding Window Technique + +Example: + +A[] = {1, 2, 3, 4, 9, 3, 8, 1 } +k = 4 +o/p: +Duplicates found +(element 3 is repeated at distance 3 which is <=k ) + +A[] = {1, 2, 3, 9, 1 } +k = 3 +o/p: +No duplicates found +(element 1 is repeated at distance 4 which is >k) + +*/ + +#include +#include +#include +using namespace std; + +bool contains(unordered_set const &set, int x) { + return set.find(x) != set.end(); +} + +bool hasDuplicates(vector &vec, int k) +{ + // create an empty set to store elements within range k + unordered_set window; + + for (int i = 0; i < vec.size(); i++) + { + // if the current element already exists in the window, + // then it is repeated within range of k + if (contains(window, vec[i])) { + return true; + } + + window.insert(vec[i]); + + if (i >= k) { + window.erase(vec[i - k]); + } + } + + // we reach here when no element is repeated within range k + return false; +} + +int main() +{ + vector vec = { 5, 6, 8, 2, 4, 6, 9 }; + int k = 4; + + if (hasDuplicates(vec, k)) { + cout << "Duplicates found"; + } + else { + cout << "No Duplicates found"; + } + + return 0; +} + +//Time complexity is O(n) and uses O(n) extra space \ No newline at end of file diff --git a/Sliding Window Problems/longest_substring_containing_distinct_characters.cpp b/Sliding Window Problems/longest_substring_containing_distinct_characters.cpp new file mode 100644 index 0000000..d77ff33 --- /dev/null +++ b/Sliding Window Problems/longest_substring_containing_distinct_characters.cpp @@ -0,0 +1,69 @@ +/* +Problem: +Given a string, find the logest substring of given string +containing distinct characters. + +Using Sliding Window Technique + +Example: + +string: 'hacktoberfest' +o/p is 'hacktoberf' + +string: 'abaa' +o/p is 'ab' + +*/ + +#include +#include +using namespace std; + +#define CHAR_RANGE 128 + +string longestSubstr(string str, int n) +{ + vector window(CHAR_RANGE); + + int begin = 0, end = 0; + + for (int low = 0, high = 0; high < n; high++) + { + if (window[str[high]]) + { + // remove characters from the left of the window till + // we encounter current character + while (str[low] != str[high]) + window[str[low++]] = false; + + low++; + } + else + { + // if current character is not present in the current + // window, include it + window[str[high]] = true; + + if (end - begin < high - low) + { + begin = low; + end = high; + }; + } + } + + return str.substr(begin, end - begin + 1); +} + +int main() +{ + string str; + + cout << "Enter string : "; + cin >> str; + + int n = str.length(); + cout << longestSubstr(str, n); + + return 0; +} \ No newline at end of file diff --git a/Sliding Window Problems/longest_substring_containing_k_distinct_characters.cpp b/Sliding Window Problems/longest_substring_containing_k_distinct_characters.cpp new file mode 100644 index 0000000..046b4b3 --- /dev/null +++ b/Sliding Window Problems/longest_substring_containing_k_distinct_characters.cpp @@ -0,0 +1,75 @@ +/* +Problem: +Given a string and a positive number k, find the logest substring of given string +containing k distinct characters. +If k is more than the number of distict characters in the string, return the whole string. + +Using Sliding Window Technique + +Example: +string: 'zootopia' +for k = 2, o/p is 'ooto' +for k = 3, o/p is 'zooto' + +*/ + +#include +#include +#include +using namespace std; + +#define CHAR_RANGE 128 + +string longestSubstr(string str, int k, int n) +{ + // for longest substring boundaries + int end = 0, begin = 0; + + unordered_set window; + + // array to store frequency of characters present in + // current window + int freq[CHAR_RANGE] = { 0 }; + + for (int low = 0, high = 0; high < n; high++) + { + window.insert(str[high]); + freq[str[high]]++; + + while (window.size() > k) + { + // if the frequency of leftmost character becomes 0 after + // removing it in the window, remove it from set as well + if (--freq[str[low]] == 0) + window.erase(str[low]); + + low++; + } + + if (end - begin < high - low) + { + end = high; + begin = low; + } + } + + return str.substr(begin, end - begin + 1); +} + +int main() +{ + string str; + int k; + + cout << "Enter string and value of k: "; + cin >> str >> k; + + int n = str.length(); + cout << longestSubstr(str, k, n); + + return 0; +} + +/* +Time Complexity: O(n) +As it does 2 traversals of the given string \ No newline at end of file diff --git a/Sliding Window Problems/subarrays_of_array_having_distinct_elements.cpp b/Sliding Window Problems/subarrays_of_array_having_distinct_elements.cpp new file mode 100644 index 0000000..4ccbaa5 --- /dev/null +++ b/Sliding Window Problems/subarrays_of_array_having_distinct_elements.cpp @@ -0,0 +1,76 @@ +/* +Problem: +Given an array of integers, +print all maximum size sub-arrays having all distinct elements in them + +Using Sliding Window Technique + +Example: + +A[] = {1, 2, 3, 3, 2, 4, 5} +o/p: +{1, 2, 3} +{3, 2, 4, 5} +*/ + +#include +#include +using namespace std; + +void printSubArray(int A[], int i, int j, int n) +{ + //invalid input + if (i < 0 || i > j || j >= n) + return; + + for (int index = i; index < j; index++) + cout << A[index] << ", " ; + + cout << A[j] << endl; +} + +void calculate(int A[], int n) +{ + // Map to mark elements as visited in the current window + unordered_map visited; + + int right = 0, left = 0; + + while (right < n) + { + // keep increasing the window size if all elements in the + // current window are distinct + while (right < n && !visited[A[right]]) + { + visited[A[right]] = true; + right++; + } + + printSubArray(A, left, right - 1, n); + + // As soon as duplicate is found (A[right]), + // terminate the above loop and reduce the window's size + // from its left to remove the duplicate + while (right < n && visited[A[right]]) + { + visited[A[left]] = false; + left++; + } + } +} + +int main() +{ + int n; + cout << "Enter the size of the array : "; + cin >> n; + + int A[n]; + cout << "Enter the elements: " << endl; + for(int i=0; i> A[i]; + + calculate(A, n); + + return 0; +} \ No newline at end of file diff --git a/Sliding Window Problems/substring_of_string_which_are_permutations_of_another_string.cpp b/Sliding Window Problems/substring_of_string_which_are_permutations_of_another_string.cpp new file mode 100644 index 0000000..2f58fe7 --- /dev/null +++ b/Sliding Window Problems/substring_of_string_which_are_permutations_of_another_string.cpp @@ -0,0 +1,82 @@ +/* +Problem: +Find all substrings of a string that are permutations of another string. +(Find Anagrams) + +Using Sliding Window Technique + +Example: + +string1: 'ABCCDBAC' +string2: 'ABC' +o/p: +Anagram 'ABC' present at index 0 +Anagram 'BAC' present at index 5 + +*/ + +#include +#include +#include +using namespace std; + +void findAllAnagrams(string str1, string str2) +{ + int m, n; + + // invalid input + if ((m = str2.length()) > (n = str1.length())) + return; + + unordered_multiset window; + + unordered_multiset set; + + for (int i = 0; i < m; i++) + set.insert(str2[i]); + + for (int i = 0; i < n; i++) + { + if (i < m) + window.insert(str1[i]); + + else + { + // If all characters in current window matches that of + // string2, we found an anagram + if (window == set) + { + cout << "Anagram " << str1.substr(i - m, m) << + " present at index " << i - m << '\n'; + } + + auto itr = window.find(X[i - m]); + if (itr != window.end()) + window.erase(itr); + + window.insert(str1[i]); + } + } + + // if last m characters of string1 matches that of string2, + // we found an anagram + if (window == set) + { + cout << "Anagram " << X.substr(n - m, m) << + " present at index " << n - m << '\n'; + } +} + +int main() +{ + string str1; + string str2; + + findAllAnagrams(X, Y); + + return 0; +} + +//Time complexity: O((n-m)*m) +// n -> length of first string +// m -> length of second string \ No newline at end of file