Sliding Window Algorithm with Example

The sliding Window Algorithm helps us solve many simple and complex coding problems with an optimized approach and lesser time complexity. In most cases, we use the sliding window algorithm to reduce the use of nested loops and the repetitive work that we do while solving any problem. 

Sliding Window Algorithm

Why it is called Sliding Window Algorithm?

When we solve problems using this Sliding Window algorithm we try to create or find fixed-size or variable-size windows (here window is nothing but a subarray or substring) which satisfies the given condition of the problem and then we keep sliding the window by one unit to cover next subarrays. 

We can easily find the required window (subarray) using two nested loops but the sliding window algorithm helps us find all possible windows by using a single loop and here now it helps us reduce our time complexity. The name of this algorithm is quite interesting and when we start visualizing the solution using this algorithm then everyone gets satisfied with the name of this algorithm. 


When should we use Sliding Window Algorithm?

Whenever we want to use some algorithm to solve any particular problem we should always be trying to find some pattern in the given question like when we want to apply a binary search algorithm then we try to check whether the given array is sorted or not. 

There are a few points that you can check for before using the sliding window algorithm:

  • There should be some discussion related to subarray or substring in the given problem.
  • There should be some discussion related to finding the largest, smallest, maximum, minimum, or any count.
  • The problem might give us a window size denoting with variable k but if the window size is not given then it means we need to find the window size based on the given conditions.


Types of Sliding Windows.

We can solve several varieties of coding problems using the sliding window algorithm but more or less we can divide them into two different categories.

  • Fixed Size Sliding Window: In this type, the size of the window (subarray) is static for the entire duration of the program and already given in the problem. 
  • Variable Size Sliding Window: In this type, the size of the window (subarray) is dynamic and keeps on changing for the entire duration of the program and we need to calculate the required largest or smallest window size.  

Example of Fixed-size sliding window

Given an array of integers of size n, find the minimum sum of the subarray of size k. 

Example 1:

Input: arr[] = {2, 3, 5, 4, 9, 7, 1}  k = 3
Output: 10

Explanation: 
Sum of all possible subarrays of size 3
{2, 3, 5} = 2+3+5 = 10
{3, 5, 4} = 3+5+4 = 12
{5, 4, 9} = 5+4+9 = 18
{4, 9, 7} = 4+9+7 = 20
{9, 7, 1} = 9+7+1 = 17 
The minimum sum we get by adding the subarray {2, 3, 5} of size 3.

Example 2:

Input: arr[] = {5, -3, 2, 8, 4, 1} k = 2
Output: -1

Explanation:
The minimum sum we get by adding the subarray {-3, 2} of size 2

We can easily solve this problem using a brute force approach by running two nested loops for calculating the sum of all possible subarrays of size k and returning the minimum sum out of all possible. Time Complexity for this approach is O(n*k) where n is the number of elements and k is the size of the subarray.


Below is the code for the brute force approach:

//C++ Code for minimum sum of subarray of size k (O(n*k) solution)
#include<iostream>
using namespace std;

int minSubarraySum(int arr[], int n, int k){

    int minSum = INT_MAX;

    for(int i = 0; i < n-k; i++){
        int sum = 0;
        for(int j = i; j < i+k; j++){
            sum += arr[j];
        }
        minSum = min(minSum, sum);
    }
    return minSum;
}
int main(){
    int arr[] = {5, -3, 2, 8, 4, 1};
//size of given array int n = sizeof(arr)/sizeof(arr[0]); //size of subarray int k = 3; cout<<minSubarraySum(arr, n, k); }

Output:

4

  • Time Complexity: O(n*k)
  • Space Complexity: O(1)

Now let's check that can we apply the sliding window algorithm to the above problem? As we discussed above for applying the sliding window algorithm, we can check for certain conditions like the problem is saying something about subarray, the window size k is given and we need to find the minimum subarray sum. It means the given problem satisfies all our conditions so we can think about applying the fixed-size sliding window approach here.


Sliding Window Algorithm: For applying the sliding window approach to this kind of problem where the window size is fixed we first need to compute the sum of the first k elements of the array and it will give us one possible answer that we can store in a variable window_sum. Now to slide the window by one unit to the right we need to remove the calculation of the first element of the previous window and add the last element of the current window. 

Sliding window example


We first calculate the initial window_sum starting from index 0 to 0+k and then we store it as a sum of our current window (current_sum) and we update our answer variable min_sum if current_sum is lesser than min_sum (initially min_sum  = INT_MAX). 

  • current_sum = 4
  • min_sum = 4

Fixed Size Sliding window example
Now to get the sum of the next current_window we have to remove the first element from window_sum and add the last element of the current_window. Every time update the value of min_sum if the value of current_sum is smaller than min_sum.

  • current_sum = 7
  • min_sum = 4
Fixed size sliding window example steps

Similarly, again
 to get the sum of the next current_window we have to remove the first (arr[1]) element from window_sum and add the last element (arr[4]) of the current_window.
  • current_sum = 14
  • min_sum = 4

Fixed size sliding window example step 3
  • current_sum = 13
  • min_sum = 4
Below is the code implementation of a fixed-size sliding window:

//C++ Code for minmum sum of subarray of size k (Sliding Window Approach)
#include<iostream> using namespace std; //function to find minmum sum of subarray of size k int minSubarraySum(int arr[], int n, int k){ //variable to store maxSum int minSum = INT_MAX; //variable to calculate window size int i = 0, j = 0; int window_sum = 0; while(j < n){ window_sum = window_sum + arr[j]; //Window size is less than k if(j-i+1 < k){ j++; } /*we get one of the possible answer, store it and remove the calculation of ith element and slide the window by one unit*/ else if(j-i+1 == k){ minSum = min(minSum, window_sum); window_sum = window_sum - arr[i]; i++; j++; } } return minSum; } int main(){ int arr[] = {5, -3, 2, 8, 4, 1}; //size of given array int n = sizeof(arr)/sizeof(arr[0]); //size of subarray int k = 3; cout<<minSubarraySum(arr, n, k); }
Output:
4
  • Time Complexity: O(n)
  • Space Complexity: O(1)

After solving many fixed-size sliding window problems, I have observed a general pattern for this algorithm that you can also follow while solving problems.

Fixed-size Sliding Window General Format

while(j < n)
{
    /*
    In this step, we need to do calculation for 
    window formation base on given condition.
    */
    if(current_window_size < k)
       /*
       Increase the window size as it is 
       not equal to given window size k
       */
       j++;
    else if(current_window_size == k)
    {
        /*
        We get our one possible answer so store
        them in some answer variable 
        */
        /*
        Remove the calculation of ith index to 
        slide the window one unit right
        */
        /*
        Increment the vlaue of i and  j to maintain
        the window size 
        i++;
        j++;
        */
    }   
}
return answer;


Example of Variable-size sliding window

Given an integer array of size n, find the length of the longest subarray having a sum equal to k.

Example 1:

Input: arr[] = {8, 7, 3, 6, 1, 5}  k = 15
Output: 4

Explanation: 
The longest subarray with sum 15 is {3, 6, 1, 5}

Example 2:

Input: arr[] = {1, 2, 3} k = 3
Output: 2

Explanation:
The longest subarray with sum 5 is {1, 2}

Input: arr[] = {-5, 7, -14, 3, 4, 12} k = -5
Output: 5

Brute Force: We find the sum of all possible subarrays and return the length of the longest subarray having a sum equal to k. The time complexity of this approach is O(n^2) as we are calculating the sum of all subarrays.


Below is the C++ Code Implementation.

#include<iostream>
using namespace std;

//function to find longest subarray of sum k
int longestSubarraySum(int arr[], int n, int k){
    //variable to store answer
    int maxlen = 0;

    for(int i = 0; i < n; i++){
        int sum = 0;
        for(int j = i; j < n; j++){
            sum += arr[j];

            if(sum == k){
                maxlen = max(maxlen, j-i+1);
            }
        }
    }
    return maxlen;
}

int main(){
    int arr[] = {10, 5, 2, 7, 1, 9};
    //given array size
    int n = sizeof(arr)/sizeof(arr[0]);
    int k = 15;
    cout<<longestSubarraySum(arr, n, k);
}
Output:
4
  • Time Complexity: O(n^2)
  • Space Complexity: O(1)
Let's check if can we apply the sliding window algorithm to this problem. If we go through the problem description we observe that it tells us to find subarrays for a given condition and return the longest one out of them. Here the size of the window is not fixed as we need to find the longest possible subarray. Now we can think of variable-size sliding windows.

Sliding Window Algorithm: (This approach will not work for arrays containing negative numbers).
In this problem where the Window size is not fixed, we will get three conditions to handle:
  • When the sum is less than k, we need to add more variables and increment j.
  • When the sum is equal to k, we get one possible answer and store the length of the current subarray in some max variable.
  • When the sum is greater than k, then subtract the ith elements until the sum becomes less than k.
Below is the C++ Code Implementation of the variable size sliding window approach.

#include<iostream>
using namespace std;

//function to find longest subarray of sum k (Sliding Window approach)
int longestSubarraySum(int arr[], int n, int k){
    //variable to store answer
    int i = 0, j = 0, sum = 0;
    int maxlen = INT_MIN;

    while(j < n){
        sum += arr[j];
        //sum is less than k
        if(sum < k){
            j++;
        }
        //sum is equal to k
        else if(sum == k){
            maxlen = max(maxlen, j-i+1);
            j++;
        }
        //sum is greater than k
        else if(sum > k){
            //remove ith elements until sum 
            //again become equal or less than k
            while(sum > k){
                sum -= arr[i];
                i++;
            }
            if(sum == k){
                maxlen = max(maxlen, j-i+1);
            }
            j++;
        }
    }
    return maxlen;
}

int main(){
    int arr[] = {10, 5, 2, 7, 1, 9};
    //given array size
    int n = sizeof(arr)/sizeof(arr[0]);
    int k = 15;
    cout<<longestSubarraySum(arr, n, k);
}
Output:
4
  • Time Complexity: O(n)
  • Space Complexity: O(1)

After solving many variable-size sliding window problems, I have observed a general pattern for this algorithm that you can also follow while solving problems.

Variable-size Sliding Window General Format

while(j < n)
{
    /*
    we need to do [calculation] for window 
    formation base on given condition.
    */
    if(calculation < k)
    {
       /*
       Increase the window size as calculation
       is not matching with given condition k
       */
       j++;
    }   
    else if(calculation == k)
    {
        /*
        we get our one possible answer, store them in some variable
        Increment the value of j.
        */
    }
    else if(calculation > k)
    {
        /*
        start removing ith elements to from calculation
        so it again meet our condition calculation == k
        */
        while(condition > k)
        {
            //remove calculation for i
            i++;
        }
        //check if we are meeting the given condition
        j++;
    }   
}
return answer;

Static sliding windows and Dynamic sliding windows, both are totally two different cases of sliding window problems and both should be handled differently.

Sliding Window Problems:

Find Maximum Sum of a Subarray of size K.

Given an integer array of size n and a number k, find the maximum sum of a subarray of size k

Example 1:

Input: arr[] = {2, 3, 5, 2, 9, 7, 1}  k = 3
Output: 18

Explanation: 
Sum of all possible subarrays of size 3
{2, 3, 5} = 2+3+5 = 10
{3, 5, 2} = 3+5+2 = 10
{5, 2, 9} = 5+2+9 = 16
{2, 9, 7} = 2+9+7 = 18
{9, 7, 1} = 9+7+1 = 17 
The maximum sum we get by adding the subarray {2, 9, 7} of size 3.

Example 2:

Input: arr[] = {5, -3, 2, 8, 4} k = 2
Output: 12

Explanation:
The maximum sum we get by adding the subarray {8, 4} of size 2


Approach 1: Brute Force

We can run two nested loops to calculate the sum of possible subarrays of the given size k and return the maximum of all sums. The time complexity of this approach will be O(n*k) where n is the number of elements in the array and k is the size of the subarray. 


C++ Code for finding the maximum sum of a subarray of size k.

//C++ Code for maximum sum of subarray of size k 
#include<iostream>
using namespace std;

int maxSubarraySum(int arr[], int n, int k){

    int maxSum = INT_MIN;

    for(int i = 0; i < n-k; i++){
        int sum = 0;
        for(int j = i; j < i+k; j++){
            sum += arr[j];
        }
        maxSum = max(maxSum, sum);
    }
    return maxSum;
}
int main(){
    int arr[] = {2, 3, 5, 2, 9, 7, 1};
    //size of given array
    int n = sizeof(arr)/sizeof(arr[0]);
    //size of subarray
    int k = 3;
    cout<<maxSubarraySum(arr, n, k);
}
Output:
18
  • Time Complexity: O(n*k)
  • Space Complexity: O(1)
Our brute force approach will work fine for a smaller value of k but as soon as the k value goes high our time complexity will also increase. We have to think of an optimized approach and we need to check that is there any repetitive work we are doing? 
 
Approach 2: Fixed-size Sliding Window (Optimized approach).

If we observe carefully we notice that the time taken to calculate the sum of each subarray is O(k) but we can compute this calculation in O(1) time complexity for all the subarray except the first subarray of size k. 

Here we are going to use the fixed-size sliding window concept to optimize our solution where the size of our Window is given as k. First, we are going to calculate the sum of our first subarray (window) of size k, and to get the sum of the next subarray we are going to add the next element in the current sum and remove the first element of the last window. 

C++ Code for finding the maximum sum of a subarray of size k using the Sliding Window Approach.
//C++ Code for maximum sum of subarray of size k (optimized)
#include<iostream> using namespace std; //function to find maximum sum of subarray of size k int maxSubarraySum(int arr[], int n, int k){ //variable to store maxSum int maxSum = INT_MIN; //variable to calculate window size int i = 0, j = 0; int sum = 0; while(j < n){ sum = sum + arr[j]; //Window size is less than k if(j-i+1 < k){ j++; } /*we get one of the possible answer, store it and remove the calculation of ith element and slide the window by one unit*/ else if(j-i+1 == k){ maxSum = max(maxSum, sum); sum = sum - arr[i]; i++; j++; } } return maxSum; } int main(){ int arr[] = {2, 3, 5, 2, 9, 7, 1}; //size of given array int n = sizeof(arr)/sizeof(arr[0]); //size of subarray int k = 3; cout<<maxSubarraySum(arr, n, k); }
Output:
18
  • Time Complexity: O(n)
  • Space Complexity: O(1)

Quick Sort Algorithm in C++.

In our previous post, we discussed Merge Sort Algorithm and we know that Merge Sort Algorithm has O(nlogn) time complexity in the worse case and it is an in-place algorithm with O(n) space complexity. 


Here in this post, we are going to discuss the Quick Sort Algorithm which is a recursive algorithm whose average case time complexity is O(nlogn) and worse case time complexity is O(n^2) but unlike merge sort, it is an in-place algorithm with O(1) space complexity. 


Note: Quick Sort has O(n^2) time complexity in the worse case but it is much more efficient in practical scenarios that we can ignore the worse case running time by using a randomized version of Quick Sort. Sort function which is available for us by most of the programming language libraries is implemented using Quick Sort.(alert-success)


Working of Quick Sort Algorithm.

In the Quick Sort algorithm, we first select one element from the given array and there are no strict rules for picking this element we can pick any element. Now let's say we picked the last element and consider this as a pivot of our algorithm. 

Picking Pivot for of Quick Sort Algoritm

Our next step is that we need to re-arrange the given array such that all the elements smaller than the pivot are moved towards the left side of the pivot and all the elements greater than the pivot are moved towards the right of the pivot. This process is known as the partitioning of the given array. All the rearrangements are happening in the original array only.

Partition step of Quick Sort

Once the partitioning is done for the given array we can break our problem into two sub-problem where we need to sort the segment of the array present on the left side of the pivot and we need to sort the segment of the array present on the right side of the pivot. We repeat this process recursively until we are left with no or only one element. 

Quick Sort Algorithm working

Algorithm of Quick Sort.

QuickSort(Array[], start, end)

{

    if(start >= end) return;

    pindex = partition(Array[], start, end);

    QuickSort(Array[], start, pindex-1);//Before pivot

    QuickSort(Array[], pindex+1, high);//After pivot

}(alert-passed)


Working of Partition Algorithm.

Let's say the last element of the array is our pivot element and by partitioning, we will move all smaller elements to the left side of the pivot and all greater elements to the right side of the pivot. By using this algorithm each time we are placing the pivot element to its correct location in our array.

Algorithm of Partition.

Partition(Array[], start, end)

{

   pivot = Array[end];

   pindex = start;

   for(i  = start to end -1)

   { 

     if(Array[i] <= pivot)

     {

        swap(Array[i], Array[pindex]);

        pindex = pindex+1;

     }

   }

   swap(Array[pindex], Array[end]);

   return pindex;

}(alert-passed)


C++ Code Implementation of Quick Sort Algorithm.

//C++ Code for Quick Sort Algorithm
#include<iostream>
using namespace std;

/*
Partition function taken last element as a pivot
and place the pivot at its correct location in the
given array by arrranging all smaller element to 
left side of pivot and all greater element to right
side of pivot.
*/
int partition(int arr[], int start, int end){
    //pivot element
    int pivot = arr[end];
    int pindex = start;

    for(int i = start; i < end; i++){
        //current element is smaller than or equal to pivot
        if(arr[i] <= pivot){
            swap(arr[i], arr[pindex]);
            pindex = pindex+1;
        }
    }
    swap(arr[pindex], arr[end]);
    return pindex;
}
//Recursive Quick Sort function
void quickSort(int arr[], int start, int end){
    //base case
    if(start >= end) return;
    /*pindex is partitioning index or it is 
     the correct position of pivot element*/
    int pindex = partition(arr, start, end);
    quickSort(arr, start, pindex-1); //sorting before pivot
    quickSort(arr, pindex+1, end); //sorting after pivot
}

int main(){
    int arr[] = {7, 2, 1, 6, 8, 5, 3, 4};
    //Size of given array
    int n = sizeof(arr)/sizeof(arr[0]);

    cout<<"Array Before Sorting: ";
    for(int i = 0; i < n; i++){
        cout<<arr[i]<<" ";
    }

    quickSort(arr, 0, n-1);

    cout<<"\nArray After Sorting: ";
    for(int i = 0; i < n; i++){
        cout<<arr[i]<<" ";
    }
}
Output:
Array Before Sorting: 7 2 1 6 8 5 3 4
Array After Sorting: 1 2 3 4 5 6 7 8
  • Time Complexity: The average case time complexity of the QuickSort algorithm is O(nlogn) and the worst case time complexity is O(n^2)
  • Space Complexity: The space complexity of the Quick Sort algorithm is O(1) because of all the operations of and the arrangement was happing in the same given array. 
Quick sort is not a stable sorting algorithm because in a stable sorting algorithm the relative order of records with equal keys is preserved.

How To Add Signature in Gmail.

Gmail is now the most popular emails providers for many small and large businesses and for personal usage. It provides us many useful features that most Gmail users hardly use such as Gmail's Signature feature. Yes, you heard it right our favorite Gmail provides us an option to add our signature to every email we send. 


In this blog post, we are going to learn how we can automatically add our signature to every email we send or reply from Gmail.

Why do we need a Gmail Signature?

Adding a signature to any email adds recognization and authentication because it contains information about you or your company. The signature can contain details like your name your profession or the company name in which you are working or it can contain details of your social media links.


Steps to Add a Signature in Gmail.

Open your Gmail Account and click on the Settings icon in the top right corner and then click on "See all settings". 

Gmail Settings

Under General settings scroll the page a little down and search for the "Signature" option and click on "Create new".

Signature option in Gmail

You will get one popup inbox to give a name to your signature. Fill in any name of your own choice and click on "Create".

Naming Gmail Signature

Add your Gmail signature inside the given box and you can also use other given features to customize your signature by adding images and social media links.


You can check your signature default option just below create a new button and from the drop-down, you can select the name of your signature. There you will notice one checkbox "Insert signature before quoted text in replies and remove the "--" line that precedes it" check this box to add your signature to all your replies.

Adding Gmail Signature to all Emails

Now, whenever you will try to send any email your default signature will get added and if you want to remove the signature for any particular email then you can choose the quick option "Manage signature" and choose the "No signature" option from the drop-down.

Removing Default Gmail Signature

I hope you have learned the complete process of adding your signature to your Gmail but if you still face any difficulties please them in the comment section below and please do share this post if you really found this useful.

(getButton) #text=(How To Send a Confidential Email in Gmail) #icon=(link) #color=(#2339bd)

Program to Find the Sum of all Array Elements in C++.

Given an Array of integers of size n. Find the Sum of all the elements present in the given Array.

Example 1: 
Input: arr[] = {2, 5, 9, 7, 10}
Output: 33
Explanation: 2 + 5 + 9 + 7 + 10 = 33

Example 2: 
Input: arr[] = {5, -2, 10, 7, 2}
Output: 22
Explanation: 5 + (- 2) + 10 + 7 + 2 = 22

Method 1: Iterative method using for loop.

Steps to find the Sum of Array elements:
  • Declare one sum variable to store the sum of the array and initialize it with 0.  
  • Run a for loop through all the array elements and keep on adding them one by one to sum the variable.(sum = sum + arr[i])
  • Print the value of the sum. 

C++ Program to find the sum of all Array Elements.

//C++ Program to find sum of array elements
#include<iostream>
using namespace std;

//Function to return sum of array
int sum(int arr[], int n){
    int sum = 0;

    for(int i = 0; i < n; i++){
        sum = sum + arr[i];
    }

    return sum;
}

int main(){
    int arr[] = {2, 5, 9, 7, 10};
    //size of given array
    int n = sizeof(arr)/sizeof(arr[0]);

    cout<<"Sum of Array Elements: "<<sum(arr, n);
}
Output:
Sum of Array Elements: 33
  • Time Complexity: O(n)
  • Space Complexity: O(1)

Method 2: Using Recursion.

The base case of our recursive function is when the size of the array will become 0 and until we hit the base case we keep on calling our sum function each this by decreasing the size of the array by one.

//C++ Program to find sum of array elements
#include<iostream>
using namespace std;

//Recursive Function to return sum of array
int sum(int arr[], int n){
    //base case
    if(n == 0){
        return 0;
    }
    else{
        //Calling the function recursively
        return arr[0] + sum(arr+1, n-1);
    }
}

int main(){
    int arr[] = {2, 5, 9, 7, 10};
    //size of given array
    int n = sizeof(arr)/sizeof(arr[0]);

    cout<<"Sum of Array Elements: "<<sum(arr, n);
}
Output:
Sum of Array Elements: 33
    • Time Complexity: O(n)
    • Space Complexity: O(1)

    DON'T MISS

    Nature, Health, Fitness
    © all rights reserved
    made with by AlgoLesson