{"id":27606,"date":"2018-04-04T19:34:07","date_gmt":"2018-04-04T14:04:07","guid":{"rendered":"https:\/\/www.wikitechy.com\/technology\/?p=27606"},"modified":"2018-04-04T19:34:07","modified_gmt":"2018-04-04T14:04:07","slug":"c-programming-count-distinct-elements-every-window-size-k","status":"publish","type":"post","link":"https:\/\/www.wikitechy.com\/technology\/c-programming-count-distinct-elements-every-window-size-k\/","title":{"rendered":"C++ Programming &#8211; Count distinct elements in every window of size k"},"content":{"rendered":"<p>Given an array of size n and an integer k, return the of count of distinct numbers in all windows of size k.<span id=\"more-135172\"><\/span><\/p>\n<p>Example:<\/p>\n<pre>Input:  arr[] = {1, 2, 1, 3, 4, 2, 3};\r\n            k = 4\r\nOutput:\r\n3\r\n4\r\n4\r\n3\r\n\r\nExplanation:\r\nFirst window is {1, 2, 1, 3}, count of distinct numbers is 3\r\nSecond window is {2, 1, 3, 4} count of distinct numbers is 4\r\nThird window is {1, 3, 4, 2} count of distinct numbers is 4\r\nFourth window is {3, 4, 2, 3} count of distinct numbers is 3<\/pre>\n<p>A <strong>Simple Solution<\/strong> is to traverse the given array, consider every window in it and count distinct elements in the window. Below is C++ implementation of simple solution.<\/p>\n<div class=\"code-embed-wrapper\"> <div class=\"code-embed-infos\"> <span class=\"code-embed-name\">C++ Program<\/span> <\/div> <pre class=\"language-cpp code-embed-pre line-numbers\"  data-start=\"1\" data-line-offset=\"0\"><code class=\"language-cpp code-embed-code\">\/\/ Simple C++ program to count distinct elements in every<br\/>\/\/ window of size k<br\/>#include &lt;iostream&gt;<br\/>using namespace std;<br\/> <br\/>\/\/ Counts distinct elements in window of size k<br\/>int countWindowDistinct(int win[], int k)<br\/>{<br\/>    int dist_count = 0;<br\/> <br\/>    \/\/ Traverse the<br\/>    for (int i=0; i&lt;k; i++)<br\/>    {<br\/>        \/\/ Check if element arr[i] exists in arr[0..i-1]<br\/>        int j;<br\/>        for (j=0; j&lt;i; j++)<br\/>           if (win[i] == win[j])<br\/>              break;<br\/>        if (j==i)<br\/>            dist_count++;<br\/>    }<br\/>    return dist_count;<br\/>}<br\/> <br\/>\/\/ Counts distinct elements in all windows of size k<br\/>void countDistinct(int arr[], int n, int k)<br\/>{<br\/>    \/\/ Traverse through every window<br\/>    for (int i=0; i&lt;=n-k; i++)<br\/>       cout &lt;&lt; countWindowDistinct(arr+i, k) &lt;&lt; endl;<br\/>}<br\/> <br\/>\/\/ Driver program<br\/>int main()<br\/>{<br\/>    int arr[] = {1, 2, 1, 3, 4, 2, 3},  k = 4;<br\/>    int n = sizeof(arr)\/sizeof(arr[0]);<br\/>    countDistinct(arr, n, k);<br\/>    return 0;<br\/>}<\/code><\/pre> <\/div>\n<p>Output:<\/p>\n<pre>3\r\n4\r\n4\r\n3<\/pre>\n<p>Time complexity of the above solution is O(nk<sup>2<\/sup>). We can improve time complexity to O(nkLok) by modifying countWindowDistinct() to use sorting. The function can further be optimized to use <a href=\"http:\/\/geeksquiz.com\/print-distinct-elements-given-integer-array\/\" target=\"_blank\" rel=\"noopener\">hashing to find distinct elements<\/a> in a window. With hashing the time complexity becomes O(nk). Below is a different approach that works in O(n) time.<\/p>\n<p>An <strong>Efficient Solution<\/strong> is to use the count of previous window, while sliding the window. The idea is to create a hash map that stores elements of current widow. When we slide the window, we remove an element from hash and add an element. We also keep track of distinct elements. Below is algorithm.<\/p>\n<p>1) Create an empty hash map. Let hash map be hM<\/p>\n<p>2) Initialize distinct element count \u2018dist_count\u2019 as 0.<\/p>\n<p>3) Traverse through first window and insert elements of first window to hM. The elements are used as key and their counts as value in hM. Also keep updating \u2018dist_count\u2019<\/p>\n<p>4) Print \u2018dist_count\u2019 for first window.<\/p>\n<p>3) Traverse through remaining array (or other windows).<br \/>\n\u2026.a) Remove the first element of previous window.<br \/>\n\u2026\u2026.If the removed element appeared only once<br \/>\n\u2026\u2026\u2026\u2026..remove it from hM and do \u201cdist_count\u2013\u201d<br \/>\n\u2026\u2026.Else (appeared multiple times in hM)<br \/>\n\u2026\u2026\u2026\u2026..decrement its count in hM<\/p>\n<p>\u2026.a) Add the current element (last element of new window)<br \/>\n\u2026\u2026.If the added element is not present in hM<br \/>\n\u2026\u2026\u2026\u2026..add it to hM and do \u201cdist_count++\u201d<br \/>\n\u2026\u2026.Else (the added element appeared multiple times)<br \/>\n\u2026\u2026\u2026\u2026..increment its count in hM<\/p>\n<p>Below is implementation of above approach.<\/p>\n<div class=\"code-embed-wrapper\"> <div class=\"code-embed-infos\"> <span class=\"code-embed-name\">C++ Program<\/span> <\/div> <pre class=\"language-cpp code-embed-pre line-numbers\"  data-start=\"1\" data-line-offset=\"0\"><code class=\"language-cpp code-embed-code\">#include &lt;iostream&gt;<br\/>#include &lt;map&gt;<br\/>using namespace std;<br\/> <br\/>void countDistinct(int arr[], int k, int n)<br\/>{<br\/>    \/\/ Creates an empty hashmap hm<br\/>    map&lt;int, int&gt; hm;<br\/> <br\/>    \/\/ initialize distinct element count for current window<br\/>    int dist_count = 0;<br\/> <br\/>    \/\/ Traverse the first window and store count<br\/>    \/\/ of every element in hash map<br\/>    for (int i = 0; i &lt; k; i++)<br\/>    {<br\/>       if (hm[arr[i]] == 0)<br\/>       {<br\/>           dist_count++;<br\/>       }<br\/>    hm[arr[i]] += 1;<br\/>    }<br\/> <br\/>   \/\/ Print count of first window<br\/>  cout &lt;&lt; dist_count &lt;&lt; endl;<br\/> <br\/>   \/\/ Traverse through the remaining array<br\/>   for (int i = k; i &lt; n; i++)<br\/>   {<br\/>     \/\/ Remove first element of previous window<br\/>     \/\/ If there was only one occurrence, then reduce distinct count.<br\/>     if (hm[arr[i-k]] == 1)<br\/>    {<br\/>        dist_count--;<br\/>    }<br\/>   \/\/ reduce count of the removed element<br\/>   hm[arr[i-k]] -= 1;<br\/> <br\/>   \/\/ Add new element of current window<br\/>   \/\/ If this element appears first time,<br\/>   \/\/ increment distinct element count<br\/> <br\/>  if (hm[arr[i]] == 0)<br\/>  {<br\/>     dist_count++;<br\/>  }<br\/>  hm[arr[i]] += 1;<br\/> <br\/>  \/\/ Print count of current window<br\/>  cout &lt;&lt; dist_count &lt;&lt; endl;<br\/>  }<br\/>}<br\/> <br\/>int main()<br\/>{<br\/>   int arr[] = {1, 2, 1, 3, 4, 2, 3};<br\/>   int size = sizeof(arr)\/sizeof(arr[0]);<br\/>   int k = 4;<br\/>   countDistinct(arr, k, size);<br\/> <br\/>   return 0;<br\/>}<\/code><\/pre> <\/div>\n<p>Output:<\/p>\n<pre>3\r\n4\r\n4\r\n3<\/pre>\n<p>Time complexity of the above solution is O(n).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>An Efficient Solution is to use the count of previous window, while sliding the window. The idea is to create a hash map that stores elements.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[80128],"tags":[81815,81808,81810,81817,81807,81811,45366,81809,81814,40204,81812,45369,45359,81816,81813],"class_list":["post-27606","post","type-post","status-publish","format-standard","hentry","category-hashing","tag-andkon","tag-code-guide","tag-computer-shortcut-keys-list","tag-control-keyboard","tag-paste-shortcut","tag-pc-shortcut-keys","tag-shortcut","tag-shortcut-for-paste","tag-shortcut-key-for-control-panel","tag-shortcut-keys-in-computer","tag-shortcuts-in-windows","tag-system-shortcut-keys","tag-undo-shortcut","tag-undo-shortcut-key","tag-windows-shortcut-keys"],"_links":{"self":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/27606","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/comments?post=27606"}],"version-history":[{"count":0,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/27606\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/media?parent=27606"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/categories?post=27606"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/tags?post=27606"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}