Skip to content

sliding window problems #41

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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,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 <iostream>
#include <vector>
#include <unordered_set>
using namespace std;

bool contains(unordered_set<int> const &set, int x) {
return set.find(x) != set.end();
}

bool hasDuplicates(vector<int> &vec, int k)
{
// create an empty set to store elements within range k
unordered_set<int> 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<int> 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
Original file line number Diff line number Diff line change
@@ -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 <iostream>
#include <vector>
using namespace std;

#define CHAR_RANGE 128

string longestSubstr(string str, int n)
{
vector<bool> 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;
}
Original file line number Diff line number Diff line change
@@ -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 <iostream>
#include <string>
#include <unordered_set>
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<char> 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
Original file line number Diff line number Diff line change
@@ -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 <iostream>
#include <unordered_map>
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<int, bool> 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<n; i++)
cin >> A[i];

calculate(A, n);

return 0;
}
Original file line number Diff line number Diff line change
@@ -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 <iostream>
#include <string>
#include <unordered_multiset>
using namespace std;

void findAllAnagrams(string str1, string str2)
{
int m, n;

// invalid input
if ((m = str2.length()) > (n = str1.length()))
return;

unordered_multiset<char> window;

unordered_multiset<char> 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