{"id":405621,"date":"2024-06-29T18:26:37","date_gmt":"2024-06-29T18:26:37","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=405621"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2024-06-29T18:26:37","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=405621","title":{"rendered":"<span>Algorithms in Go: Dutch National Flag<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>Most solutions to algorithmic problems can be grouped into a rather small number of patterns. When we start to solve some problem, we need to think about how we would classify them. For example, can we apply <code>fast and slow<\/code>algorithmic pattern or do we need to use <code>cyclic sort<\/code>pattern? Some of the problems have several solutions with different patterns. In this article of series <a href=\"https:\/\/habr.com\/en\/post\/545986\/\" rel=\"noopener noreferrer nofollow\">Algorithms in Go<\/a> we consider an algorithmic pattern that solves an entire class of problems related to array processing. <\/p>\n<p>The flag of the Netherlands consists of three colors: red, white and blue. Given balls of these three colors arranged randomly in a line (it does not matter how many balls there are), the task is to arrange them such that all balls of the same color are together and their collective color groups are in the correct order.<\/p>\n<p>For simplicity instead of colors red, white, and blue we will be dealing with <code>ones<\/code>, <code>twos<\/code> and <code>zeroes<\/code>. <\/p>\n<p>Let&#8217;s start with our intuition. We have an array of zeroth, ones, and twos. How would we sort it? Well, we could put aside all <code>zeroes<\/code>into some bucket, all <code>ones<\/code>into another bucket, and all <code>twos<\/code>into the third. Then we can fetch all items from the first bucket, then from the second, and from the last bucket, and restore all the items. This approach is perfectly fine and has a great performance. We touch all the elements when we iterate through the array, and then we iterate through all the elements once more when we &#171;reassamble&#187; the array. So, the overall time complexity is <code>O(n) + O(n) ~= O(n)<\/code>. The space complexity is also <code>O(n)<\/code> as we need to store all items in the buckets. <\/p>\n<p>Can we do better than that? There is no way to improve our time complexity. However, we can think of a more efficient algorithm in regard to space complexity. How would we solve the problem <strong>without<\/strong> the additional buckets, i.e <code>in-place.<\/code><\/p>\n<p>Let&#8217;s make a <strong>leap of faith<\/strong> and pretend that somehow we were able to process a part of the array. We iterate through part of the array and put encountered <code>zeroes<\/code> and <code>ones<\/code> at the beginning of the array, and <code>twos<\/code> at the end of the array. Now, we switched to the next index <code>i<\/code> with some unprocessed value <code>x<\/code>. What should we do there?<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/978\/eb4\/c59\/978eb4c597eff6b9ed0c58366d9320df\" width=\"1678\" height=\"595\"\/><figcaption><\/figcaption><\/figure>\n<p>In this case, there are three possibilities: <code>x<\/code> could be equal to <code>0<\/code>, <code>1<\/code> or <code>2<\/code>. <\/p>\n<p>Let&#8217;s say <code>x<\/code> is equal to <code>2<\/code>. Where should we put it? We already have some twos at the end of the array, so we need to put current <code>two<\/code> right before the start of the known twos. We don&#8217;t know which value is located before the start of known twos. Let&#8217;s call this value <code>y<\/code>. <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b86\/555\/a8e\/b86555a8ef8b202aee7387a61063312b\" width=\"1760\" height=\"567\"\/><figcaption><\/figcaption><\/figure>\n<p>We swap our current value and <code>y<\/code>. As we don&#8217;t know the value <code>y<\/code> at our current index <code>i<\/code>, it is possible that we need to swap it once more. So we don&#8217;t proceed to the next value, i.e. we don&#8217;t increase our running pointer <code>i<\/code>. After this operation we have:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6fc\/284\/2d9\/6fc2842d99401eb58423a0da727cb055\" width=\"1640\" height=\"609\"\/><figcaption><\/figcaption><\/figure>\n<p>We note that we now have one more <code>two<\/code> at the end, so we need to shift the start of the known twos. This fact tells us that we need to have one more pointer that points to the start of the processed <code>twos<\/code> , let&#8217;s denote this pointer as <code>high<\/code>. When we encounter another <code>two<\/code> we put it right before this pointer.<\/p>\n<p>Now, let&#8217;s consider the case when <code>x<\/code> is equal to <code>zero<\/code>. We need to put this <code>zero<\/code>right after the last processed <code>zero<\/code><\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ba4\/af5\/ce8\/ba4af5ce80c0083998bc1316abb3bf69\" width=\"1818\" height=\"549\"\/><figcaption><\/figcaption><\/figure>\n<p>After this operation, we need to shift the end of known zeroes to the right. Therefore, we will have another pointer <code>low<\/code> that points to the end of known zeroes. When we encounter another <code>zero<\/code> we put it to the right of this pointer. <\/p>\n<p>We swap the items at indices <code>i<\/code> and <code>low+1<\/code>. As index <code>low+1<\/code> goes directly after index <code>low<\/code> that denotes the end of zeroes, the value at index <code>low+1<\/code> will always be equal to <code>one<\/code>.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/614\/8ff\/d29\/6148ffd29220ee0a7b2a58350355eab6\" width=\"1899\" height=\"526\"\/><figcaption><\/figcaption><\/figure>\n<p>Now, what do we do with ones? That&#8217;s a tricky part because, actually, we do nothing. The item is already in place, so we are free to proceed to the next item. <\/p>\n<p>Ok, this could work when we are in the <strong>middle of the processing. But how do we start?<\/strong><\/p>\n<p>The running pointer is initialized with a value equal to zero. We don&#8217;t have any known <code>twos<\/code> yet, so the start of twos is equal to the length of the array. In this way, the first encountered <code>two<\/code> will be put at the very end of the array which seems logical. We don&#8217;t have any known <code>zeroes<\/code> either, so the end of <code>zeroes<\/code> is equal to minus one. Therefore, the first <code>encountered<\/code> zero will be put at the very beginning of the array and that&#8217;s exactly what we want. <\/p>\n<p>Right, how do we know where should we stop? We could iterate through the whole array, but at some point the movement becomes redundant. When our running pointer becomes equal to <code>high<\/code>, we know for sure that the value at that index is equal to <code>two<\/code> and we have already processed it. Therefore, we can stop there. If we don&#8217;t have any <code>twos<\/code> then the value of <code>high<\/code>is equal to the length of the array, and we stop at the last item.<\/p>\n<p>Finally, we can implement the algorithm in Go:<\/p>\n<pre><code class=\"go\">func Sort(arr []int) {   low := -1   high := len(arr)      for i := 0; i &lt; high; {     val := arr[i]     switch val {       case 0:       arr[i], arr[low+1] = arr[low+1], arr[i]         low++         i++       case 1:         i++       case 2:         arr[i], arr[high-1] = arr[high-1], arr[i]         high--     } }<\/code><\/pre>\n<p>In this post, we implemented a solution for Dutch National Flag problem. This is one of the most popular algorithmic patterns that solve an entire class of problems. More algorithmic patterns such as <a href=\"https:\/\/habr.com\/en\/post\/531444\/\" rel=\"noopener noreferrer nofollow\">Sliding Window<\/a> or <a href=\"https:\/\/habr.com\/en\/post\/545980\/\" rel=\"noopener noreferrer nofollow\">Iterative Postorder Traversal<\/a><a href=\"https:\/\/habr.com\/en\/post\/543618\/\" rel=\"noopener noreferrer nofollow\"> <\/a>can be found in the series <a href=\"https:\/\/habr.com\/en\/post\/545986\/\" rel=\"noopener noreferrer nofollow\">Algorithms in Go.<\/a> <\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/541130\/\"> https:\/\/habr.com\/ru\/articles\/541130\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>Most solutions to algorithmic problems can be grouped into a rather small number of patterns. When we start to solve some problem, we need to think about how we would classify them. For example, can we apply <code>fast and slow<\/code>algorithmic pattern or do we need to use <code>cyclic sort<\/code>pattern? Some of the problems have several solutions with different patterns. In this article of series <a href=\"https:\/\/habr.com\/en\/post\/545986\/\" rel=\"noopener noreferrer nofollow\">Algorithms in Go<\/a> we consider an algorithmic pattern that solves an entire class of problems related to array processing. <\/p>\n<p>The flag of the Netherlands consists of three colors: red, white and blue. Given balls of these three colors arranged randomly in a line (it does not matter how many balls there are), the task is to arrange them such that all balls of the same color are together and their collective color groups are in the correct order.<\/p>\n<p>For simplicity instead of colors red, white, and blue we will be dealing with <code>ones<\/code>, <code>twos<\/code> and <code>zeroes<\/code>. <\/p>\n<p>Let&#8217;s start with our intuition. We have an array of zeroth, ones, and twos. How would we sort it? Well, we could put aside all <code>zeroes<\/code>into some bucket, all <code>ones<\/code>into another bucket, and all <code>twos<\/code>into the third. Then we can fetch all items from the first bucket, then from the second, and from the last bucket, and restore all the items. This approach is perfectly fine and has a great performance. We touch all the elements when we iterate through the array, and then we iterate through all the elements once more when we &#171;reassamble&#187; the array. So, the overall time complexity is <code>O(n) + O(n) ~= O(n)<\/code>. The space complexity is also <code>O(n)<\/code> as we need to store all items in the buckets. <\/p>\n<p>Can we do better than that? There is no way to improve our time complexity. However, we can think of a more efficient algorithm in regard to space complexity. How would we solve the problem <strong>without<\/strong> the additional buckets, i.e <code>in-place.<\/code><\/p>\n<p>Let&#8217;s make a <strong>leap of faith<\/strong> and pretend that somehow we were able to process a part of the array. We iterate through part of the array and put encountered <code>zeroes<\/code> and <code>ones<\/code> at the beginning of the array, and <code>twos<\/code> at the end of the array. Now, we switched to the next index <code>i<\/code> with some unprocessed value <code>x<\/code>. What should we do there?<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>In this case, there are three possibilities: <code>x<\/code> could be equal to <code>0<\/code>, <code>1<\/code> or <code>2<\/code>. <\/p>\n<p>Let&#8217;s say <code>x<\/code> is equal to <code>2<\/code>. Where should we put it? We already have some twos at the end of the array, so we need to put current <code>two<\/code> right before the start of the known twos. We don&#8217;t know which value is located before the start of known twos. Let&#8217;s call this value <code>y<\/code>. <\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>We swap our current value and <code>y<\/code>. As we don&#8217;t know the value <code>y<\/code> at our current index <code>i<\/code>, it is possible that we need to swap it once more. So we don&#8217;t proceed to the next value, i.e. we don&#8217;t increase our running pointer <code>i<\/code>. After this operation we have:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>We note that we now have one more <code>two<\/code> at the end, so we need to shift the start of the known twos. This fact tells us that we need to have one more pointer that points to the start of the processed <code>twos<\/code> , let&#8217;s denote this pointer as <code>high<\/code>. When we encounter another <code>two<\/code> we put it right before this pointer.<\/p>\n<p>Now, let&#8217;s consider the case when <code>x<\/code> is equal to <code>zero<\/code>. We need to put this <code>zero<\/code>right after the last processed <code>zero<\/code><\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>After this operation, we need to shift the end of known zeroes to the right. Therefore, we will have another pointer <code>low<\/code> that points to the end of known zeroes. When we encounter another <code>zero<\/code> we put it to the right of this pointer. <\/p>\n<p>We swap the items at indices <code>i<\/code> and <code>low+1<\/code>. As index <code>low+1<\/code> goes directly after index <code>low<\/code> that denotes the end of zeroes, the value at index <code>low+1<\/code> will always be equal to <code>one<\/code>.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>Now, what do we do with ones? That&#8217;s a tricky part because, actually, we do nothing. The item is already in place, so we are free to proceed to the next item. <\/p>\n<p>Ok, this could work when we are in the <strong>middle of the processing. But how do we start?<\/strong><\/p>\n<p>The running pointer is initialized with a value equal to zero. We don&#8217;t have any known <code>twos<\/code> yet, so the start of twos is equal to the length of the array. In this way, the first encountered <code>two<\/code> will be put at the very end of the array which seems logical. We don&#8217;t have any known <code>zeroes<\/code> either, so the end of <code>zeroes<\/code> is equal to minus one. Therefore, the first <code>encountered<\/code> zero will be put at the very beginning of the array and that&#8217;s exactly what we want. <\/p>\n<p>Right, how do we know where should we stop? We could iterate through the whole array, but at some point the movement becomes redundant. When our running pointer becomes equal to <code>high<\/code>, we know for sure that the value at that index is equal to <code>two<\/code> and we have already processed it. Therefore, we can stop there. If we don&#8217;t have any <code>twos<\/code> then the value of <code>high<\/code>is equal to the length of the array, and we stop at the last item.<\/p>\n<p>Finally, we can implement the algorithm in Go:<\/p>\n<pre><code class=\"go\">func Sort(arr []int) {   low := -1   high := len(arr)      for i := 0; i &lt; high; {     val := arr[i]     switch val {       case 0:       arr[i], arr[low+1] = arr[low+1], arr[i]         low++         i++       case 1:         i++       case 2:         arr[i], arr[high-1] = arr[high-1], arr[i]         high--     } }<\/code><\/pre>\n<p>In this post, we implemented a solution for Dutch National Flag problem. This is one of the most popular algorithmic patterns that solve an entire class of problems. More algorithmic patterns such as <a href=\"https:\/\/habr.com\/en\/post\/531444\/\" rel=\"noopener noreferrer nofollow\">Sliding Window<\/a> or <a href=\"https:\/\/habr.com\/en\/post\/545980\/\" rel=\"noopener noreferrer nofollow\">Iterative Postorder Traversal<\/a><a href=\"https:\/\/habr.com\/en\/post\/543618\/\" rel=\"noopener noreferrer nofollow\"> <\/a>can be found in the series <a href=\"https:\/\/habr.com\/en\/post\/545986\/\" rel=\"noopener noreferrer nofollow\">Algorithms in Go.<\/a> <\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/541130\/\"> https:\/\/habr.com\/ru\/articles\/541130\/<\/a><br \/><\/br><\/br><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-405621","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/405621","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=405621"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/405621\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=405621"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=405621"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=405621"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}