{"id":25247,"date":"2017-10-15T16:14:58","date_gmt":"2017-10-15T10:44:58","guid":{"rendered":"https:\/\/www.wikitechy.com\/technology\/?p=25247"},"modified":"2017-10-15T16:14:58","modified_gmt":"2017-10-15T10:44:58","slug":"sort-n-numbers-range-0-n2-1-linear-time","status":"publish","type":"post","link":"https:\/\/www.wikitechy.com\/technology\/sort-n-numbers-range-0-n2-1-linear-time\/","title":{"rendered":"Sort n numbers in range from 0 to n^2 \u2013 1 in linear time"},"content":{"rendered":"<p>Given an array of numbers of size n. It is also given that the array elements are in range from 0 to n<sup>2<\/sup>\u2013 1. Sort the given array in linear time.<span id=\"more-127333\"><\/span><\/p>\n<pre>Examples:\r\nSince there are 5 elements, the elements can be from 0 to 24.\r\nInput: arr[] = {0, 23, 14, 12, 9}\r\nOutput: arr[] = {0, 9, 12, 14, 23}\r\n\r\nSince there are 3 elements, the elements can be from 0 to 8.\r\nInput: arr[] = {7, 0, 2}\r\nOutput: arr[] = {0, 2, 7}\r\n<\/pre>\n<p><em><strong>We strongly recommend to minimize the browser and try this yourself first.<\/strong><\/em><\/p>\n<p><strong>Solution:<\/strong> If we use <a href=\"http:\/\/www.geeksforgeeks.org\/counting-sort\/\" target=\"_blank\" rel=\"noopener noreferrer\">Counting Sort<\/a>, it would take O(n^2) time as the given range is of size n^2. Using any comparison based sorting like<a href=\"http:\/\/geeksquiz.com\/merge-sort\/\" target=\"_blank\" rel=\"noopener noreferrer\"> Merge Sort<\/a>, <a href=\"http:\/\/geeksquiz.com\/heap-sort\/\" target=\"_blank\" rel=\"noopener noreferrer\">Heap Sort<\/a>, .. etc would take O(nLogn) time.<br \/>\nNow question arises how to do this in 0(n)? Firstly, is it possible? Can we use data given in question? n numbers in range from 0 to n<sup>2<\/sup> \u2013 1?<br \/>\nThe idea is to use <a href=\"http:\/\/www.geeksforgeeks.org\/radix-sort\/\" target=\"_blank\" rel=\"noopener noreferrer\">Radix Sort<\/a>. Following is standard Radix Sort algorithm.<\/p>\n<pre>1) Do following for each digit i where i varies from least \r\n   significant digit to the most significant digit.\r\n\u2026\u2026\u2026\u2026..a) Sort input array using counting sort (or any stable \r\n         sort) according to the i\u2019th digit\r\n<\/pre>\n<p>Let there be d digits in input integers. Radix Sort takes O(d*(n+b)) time where b is the base for representing numbers, for example, for decimal system, b is 10. Since n<sup>2<\/sup>-1 is the maximum possible value, the value of d would be O(log<sub>b<\/sub>(n)). So overall time complexity is O((n+b)*O(log<sub>b<\/sub>(n)). Which looks more than the time complexity of comparison based sorting algorithms for a large k. The idea is to change base b. If we set b as n, the value of O(log<sub>b<\/sub>(n)) becomes O(1) and overall time complexity becomes O(n).<\/p>\n<pre>arr[] = {0, 10, 13, 12, 7}\r\n\r\nLet us consider the elements in base 5. For example 13 in\r\nbase 5 is 23, and 7 in base 5 is 12.\r\narr[] = {00(0), 20(10), 23(13), 22(12), 12(7)}\r\n\r\nAfter first iteration (Sorting according to the last digit in \r\nbase 5),  we get.\r\narr[] = {0<u>0<\/u>(0), 2<u>0<\/u>(10), 1<u>2<\/u>(7), 2<u>2<\/u>(12), 2<u>3<\/u>(13)}\r\n\r\nAfter second iteration, we get\r\narr[] = {<u>0<\/u>0(0), <u>1<\/u>2(7), <u>2<\/u>0(10), <u>2<\/u>2(12), <u>2<\/u>3(13)}\r\n<\/pre>\n<p>Following is C++ implementation to sort an array of size n where elements are in range from 0 to n<sup>2<\/sup> \u2013 1.<\/p>\n[ad type=&#8221;banner&#8221;]\n<p><strong>C++<\/strong><\/p>\n<div class=\"code-embed-wrapper\"> <div class=\"code-embed-infos\"> <span class=\"code-embed-name\">c++<\/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\/>using namespace std;<br\/> <br\/>\/\/ A function to do counting sort of arr[] according to<br\/>\/\/ the digit represented by exp.<br\/>int countSort(int arr[], int n, int exp)<br\/>{<br\/> <br\/>    int output[n]; \/\/ output array<br\/>    int i, count[n] ;<br\/>    for (int i=0; i &lt; n; i++)<br\/>       count[i] = 0;<br\/> <br\/>    \/\/ Store count of occurrences in count[]<br\/>    for (i = 0; i &lt; n; i++)<br\/>        count[ (arr[i]\/exp)%n ]++;<br\/> <br\/>    \/\/ Change count[i] so that count[i] now contains actual<br\/>    \/\/ position of this digit in output[]<br\/>    for (i = 1; i &lt; n; i++)<br\/>        count[i] += count[i - 1];<br\/> <br\/>    \/\/ Build the output array<br\/>    for (i = n - 1; i &gt;= 0; i--)<br\/>    {<br\/>        output[count[ (arr[i]\/exp)%n] - 1] = arr[i];<br\/>        count[(arr[i]\/exp)%n]--;<br\/>    }<br\/> <br\/>    \/\/ Copy the output array to arr[], so that arr[] now<br\/>    \/\/ contains sorted numbers according to curent digit<br\/>    for (i = 0; i &lt; n; i++)<br\/>        arr[i] = output[i];<br\/>}<br\/> <br\/> <br\/>\/\/ The main function to that sorts arr[] of size n using Radix Sort<br\/>void sort(int arr[], int n)<br\/>{<br\/>    \/\/ Do counting sort for first digit in base n. Note that<br\/>    \/\/ instead of passing digit number, exp (n^0 = 0) is passed.<br\/>    countSort(arr, n, 1);<br\/> <br\/>    \/\/ Do counting sort for second digit in base n. Note that<br\/>    \/\/ instead of passing digit number, exp (n^1 = n) is passed.<br\/>    countSort(arr, n, n);<br\/>}<br\/> <br\/>\/\/ A utility function to print an array<br\/>void printArr(int arr[], int n)<br\/>{<br\/>    for (int i = 0; i &lt; n; i++)<br\/>        cout &lt;&lt; arr[i] &lt;&lt; &quot; &quot;;<br\/>}<br\/> <br\/>\/\/ Driver program to test above functions<br\/>int main()<br\/>{<br\/>    \/\/ Since array size is 7, elements should be from 0 to 48<br\/>    int arr[] = {40, 12, 45, 32, 33, 1, 22};<br\/>    int n = sizeof(arr)\/sizeof(arr[0]);<br\/>    cout &lt;&lt; &quot;Given array is \\n&quot;;<br\/>    printArr(arr, n);<br\/> <br\/>    sort(arr, n);<br\/> <br\/>    cout &lt;&lt; &quot;\\nSorted array is \\n&quot;;<br\/>    printArr(arr, n);<br\/>    return 0;<br\/>}<\/code><\/pre> <\/div>\n<p><strong>JAVA<\/strong><\/p>\n<div class=\"code-embed-wrapper\"> <div class=\"code-embed-infos\"> <span class=\"code-embed-name\">JAVA<\/span> <\/div> <pre class=\"language-java code-embed-pre line-numbers\"  data-start=\"1\" data-line-offset=\"0\"><code class=\"language-java code-embed-code\">\/ Java program to sort an array of size n where elements are<br\/>\/\/ in range from 0 to n^2 \u2013 1.<br\/>class Sort1ToN2<br\/>{<br\/>    \/\/ A function to do counting sort of arr[] according to<br\/>    \/\/ the digit represented by exp.<br\/>    void countSort(int arr[], int n, int exp)<br\/>    {<br\/>        int output[] = new int[n]; \/\/ output array<br\/>        int i, count[] = new int[n] ;<br\/>        for (i=0; i &lt; n; i++)<br\/>           count[i] = 0;<br\/> <br\/>        \/\/ Store count of occurrences in count[]<br\/>        for (i = 0; i &lt; n; i++)<br\/>            count[ (arr[i]\/exp)%n ]++;<br\/> <br\/>        \/\/ Change count[i] so that count[i] now contains actual<br\/>        \/\/ position of this digit in output[]<br\/>        for (i = 1; i &lt; n; i++)<br\/>            count[i] += count[i - 1];<br\/> <br\/>        \/\/ Build the output array<br\/>        for (i = n - 1; i &gt;= 0; i--)<br\/>        {<br\/>            output[count[ (arr[i]\/exp)%n] - 1] = arr[i];<br\/>            count[(arr[i]\/exp)%n]--;<br\/>        }<br\/> <br\/>        \/\/ Copy the output array to arr[], so that arr[] now<br\/>        \/\/ contains sorted numbers according to curent digit<br\/>        for (i = 0; i &lt; n; i++)<br\/>            arr[i] = output[i];<br\/>    }<br\/> <br\/> <br\/>    \/\/ The main function to that sorts arr[] of size n using Radix Sort<br\/>    void sort(int arr[], int n)<br\/>    {<br\/>        \/\/ Do counting sort for first digit in base n. Note that<br\/>        \/\/ instead of passing digit number, exp (n^0 = 0) is passed.<br\/>        countSort(arr, n, 1);<br\/> <br\/>        \/\/ Do counting sort for second digit in base n. Note that<br\/>        \/\/ instead of passing digit number, exp (n^1 = n) is passed.<br\/>        countSort(arr, n, n);<br\/>    }<br\/> <br\/>    \/\/ A utility function to print an array<br\/>    void printArr(int arr[], int n)<br\/>    {<br\/>        for (int i = 0; i &lt; n; i++)<br\/>            System.out.print(arr[i]+&quot; &quot;);<br\/>    }<br\/> <br\/>    \/\/ Driver program to test above functions<br\/>    public static void main(String args[])<br\/>    {<br\/>        Sort1ToN2 ob = new Sort1ToN2();<br\/> <br\/>        \/\/ Since array size is 7, elements should be from 0 to 48<br\/>        int arr[] = {40, 12, 45, 32, 33, 1, 22};<br\/>        int n = arr.length;<br\/>        System.out.println(&quot;Given array&quot;);<br\/>        ob.printArr(arr, n);<br\/> <br\/>        ob.sort(arr, n);<br\/> <br\/>        System.out.println(&quot;Sorted array&quot;);<br\/>        ob.printArr(arr, n);<br\/>    }<br\/>}<\/code><\/pre> <\/div>\n<p><strong>Output:<\/strong><\/p>\n<pre>Given array is\r\n40 12 45 32 33 1 22\r\nSorted array is\r\n1 12 22 32 33 40 45<\/pre>\n<p><strong>How to sort if range is from 1 to n<sup>2<\/sup>?<\/strong><br \/>\nIf range is from 1 to n n<sup>2<\/sup>, the above process can not be directly applied, it must be changed. Consider n = 100 and range from 1 to 10000. Since the base is 100, a digit must be from 0 to 99 and there should be 2 digits in the numbers. But the number 10000 has more than 2 digits. So to sort numbers in a range from 1 to n<sup>2<\/sup>, we can use following process.<br \/>\n1) Subtract all numbers by 1.<br \/>\n2) Since the range is now 0 to n<sup>2<\/sup>, do counting sort twice as done in the above implementation.<br \/>\n3) After the elements are sorted, add 1 to all numbers to obtain the original numbers.<\/p>\n<p><strong>How to sort if range is from 0 to n^3 -1?<\/strong><br \/>\nSince there can be 3 digits in base n, we need to call counting sort 3 times.<\/p>\n[ad type=&#8221;banner&#8221;]\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sort n numbers in range from 0 to n^2 \u2013 1 in linear time &#8211; Searching and sorting &#8211; If we use Counting Sort, it would take O(n^2) time as the given range is of size n^2. Using any comparison based sorting like Merge Sort, Heap Sort, .. etc would take O(nLogn) time.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[69969,71670,83513],"tags":[],"class_list":["post-25247","post","type-post","status-publish","format-standard","hentry","category-algorithm","category-searching-and-sorting","category-sort-n-numbers"],"_links":{"self":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/25247","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\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/comments?post=25247"}],"version-history":[{"count":0,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/25247\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/media?parent=25247"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/categories?post=25247"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/tags?post=25247"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}