You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{"payload":{"allShortcutsEnabled":false,"path":"Count Occurrences","repo":{"id":283265754,"defaultBranch":"master","name":"swift-algorithm-club","ownerLogin":"orchca","currentUserCanPush":false,"isFork":true,"isEmpty":false,"createdAt":"2020-07-28T16:18:29.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/3979323?v=4","public":true,"private":false,"isOrgOwned":false},"currentUser":null,"refInfo":{"name":"master","listCacheKey":"v0:1616582547.416779","canEdit":false,"refType":"branch","currentOid":"bcd9eb3e6b8bb7c8f67eb962b065b16ef5c9f25b"},"tree":{"items":[{"name":"CountOccurrences.playground","path":"Count Occurrences/CountOccurrences.playground","contentType":"directory"},{"name":"CountOccurrences.swift","path":"Count Occurrences/CountOccurrences.swift","contentType":"file"},{"name":"README.markdown","path":"Count Occurrences/README.markdown","contentType":"file"}],"templateDirectorySuggestionUrl":null,"readme":{"displayName":"README.markdown","richText":"\u003carticle class=\"markdown-body entry-content container-lg\" itemprop=\"text\"\u003e\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch1 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eCount Occurrences\u003c/h1\u003e\u003ca id=\"user-content-count-occurrences\" class=\"anchor\" aria-label=\"Permalink: Count Occurrences\" href=\"#count-occurrences\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eGoal: Count how often a certain value appears in an array.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe obvious way to do this is with a \u003ca href=\"/orchca/swift-algorithm-club/blob/master/Linear%20Search\"\u003elinear search\u003c/a\u003e from the beginning of the array until the end, keeping count of how often you come across the value. That is an \u003cstrong\u003eO(n)\u003c/strong\u003e algorithm.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eHowever, if the array is sorted you can do it much faster, in \u003cstrong\u003eO(log n)\u003c/strong\u003e time, by using a modification of \u003ca href=\"/orchca/swift-algorithm-club/blob/master/Binary%20Search\"\u003ebinary search\u003c/a\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eLet's say we have the following array:\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"[ 0, 1, 1, 3, 3, 3, 3, 6, 8, 10, 11, 11 ]\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003e[ 0, 1, 1, 3, 3, 3, 3, 6, 8, 10, 11, 11 ]\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIf we want to know how often the value \u003ccode\u003e3\u003c/code\u003e occurs, we can do a regular binary search for \u003ccode\u003e3\u003c/code\u003e. That could give us any of these four indices:\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"[ 0, 1, 1, 3, 3, 3, 3, 6, 8, 10, 11, 11 ]\n * * * *\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003e[ 0, 1, 1, 3, 3, 3, 3, 6, 8, 10, 11, 11 ]\n * * * *\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eBut that still doesn't tell you how many other \u003ccode\u003e3\u003c/code\u003es there are. To find those other \u003ccode\u003e3\u003c/code\u003es, you'd still have to do a linear search to the left and a linear search to the right. That will be fast enough in most cases, but in the worst case -- when the array consists of nothing but \u003ccode\u003e3\u003c/code\u003es -- it still takes \u003cstrong\u003eO(n)\u003c/strong\u003e time.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe trick is to use two binary searches, one to find where the \u003ccode\u003e3\u003c/code\u003es start (the left boundary), and one to find where they end (the right boundary).\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIn code this looks as follows:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-swift notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"func countOccurrences\u0026lt;T: Comparable\u0026gt;(of key: T, in array: [T]) -\u0026gt; Int {\n var leftBoundary: Int {\n var low = 0\n var high = array.count\n while low \u0026lt; high {\n let midIndex = low + (high - low)/2\n if a[midIndex] \u0026lt; key {\n low = midIndex + 1\n } else {\n high = midIndex\n }\n }\n return low\n }\n\n var rightBoundary: Int {\n var low = 0\n var high = array.count\n while low \u0026lt; high {\n let midIndex = low + (high - low)/2\n if a[midIndex] \u0026gt; key {\n high = midIndex\n } else {\n low = midIndex + 1\n }\n }\n return low\n }\n\n return rightBoundary - leftBoundary\n}\"\u003e\u003cpre\u003e\u003cspan class=\"pl-en\"\u003efunc\u003c/span\u003e countOccurrences\u003cspan class=\"pl-c1\"\u003e\u0026lt;\u003c/span\u003eT\u003cspan class=\"pl-kos\"\u003e:\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eComparable\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003eof key\u003cspan class=\"pl-kos\"\u003e:\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eT\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e in array\u003cspan class=\"pl-kos\"\u003e:\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003eT\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e-\u0026gt;\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eInt\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-k\"\u003evar\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eleftBoundary\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e:\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eInt\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-k\"\u003evar\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003elow\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e\n \u003cspan class=\"pl-k\"\u003evar\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ehigh\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e array\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003ecount\n \u003cspan class=\"pl-k\"\u003ewhile\u003c/span\u003e low \u003cspan class=\"pl-c1\"\u003e\u0026lt;\u003c/span\u003e high \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-k\"\u003elet\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emidIndex\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e low \u003cspan class=\"pl-c1\"\u003e+\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003ehigh \u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e low\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e/\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e2\u003c/span\u003e\n \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ea\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003emidIndex\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e\u0026lt;\u003c/span\u003e key \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n low \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e midIndex \u003cspan class=\"pl-c1\"\u003e+\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eelse\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n high \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e midIndex\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e low\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\n \u003cspan class=\"pl-k\"\u003evar\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003erightBoundary\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e:\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eInt\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-k\"\u003evar\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003elow\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e\n \u003cspan class=\"pl-k\"\u003evar\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ehigh\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e array\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003ecount\n \u003cspan class=\"pl-k\"\u003ewhile\u003c/span\u003e low \u003cspan class=\"pl-c1\"\u003e\u0026lt;\u003c/span\u003e high \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-k\"\u003elet\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emidIndex\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e low \u003cspan class=\"pl-c1\"\u003e+\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003ehigh \u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e low\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e/\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e2\u003c/span\u003e\n \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ea\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003emidIndex\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e\u0026gt;\u003c/span\u003e key \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n high \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e midIndex\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eelse\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n low \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e midIndex \u003cspan class=\"pl-c1\"\u003e+\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e low\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\n \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e rightBoundary \u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e leftBoundary\n\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eNotice that the variables \u003ccode\u003eleftBoundary\u003c/code\u003e and \u003ccode\u003erightBoundary\u003c/code\u003e are very similar to the \u003ca href=\"/orchca/swift-algorithm-club/blob/master/Binary%20Search\"\u003ebinary search\u003c/a\u003e algorithm. The big difference is that they don't stop when they find the search key, but keep going. Also, notice that we constrain the type \u003ccode\u003eT\u003c/code\u003e to be Comparable so that the algorithm can be applied to an array of Strings, Ints or other types that conform to the Swift Comparable protocol.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eTo test this algorithm, copy the code to a playground and then do:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-swift notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"let a = [ 0, 1, 1, 3, 3, 3, 3, 6, 8, 10, 11, 11 ]\n\ncountOccurrences(of: 3, in: a) // returns 4\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003elet\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ea\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e3\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e3\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e3\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e3\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e6\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e8\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e10\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e11\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e11\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003ecountOccurrences\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003eof\u003cspan class=\"pl-kos\"\u003e:\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e3\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e in\u003cspan class=\"pl-kos\"\u003e:\u003c/span\u003e a\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e // returns 4\u003c/pre\u003e\u003c/div\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eRemember:\u003c/strong\u003e If you use your own array, make sure it is sorted first!\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp dir=\"auto\"\u003eLet's walk through the example. The array is:\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"[ 0, 1, 1, 3, 3, 3, 3, 6, 8, 10, 11, 11 ]\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003e[ 0, 1, 1, 3, 3, 3, 3, 6, 8, 10, 11, 11 ]\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eTo find the left boundary, we start with \u003ccode\u003elow = 0\u003c/code\u003e and \u003ccode\u003ehigh = 12\u003c/code\u003e. The first mid index is \u003ccode\u003e6\u003c/code\u003e:\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"[ 0, 1, 1, 3, 3, 3, 3, 6, 8, 10, 11, 11 ]\n *\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003e[ 0, 1, 1, 3, 3, 3, 3, 6, 8, 10, 11, 11 ]\n *\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eWith a regular binary search you'd be done now, but here we're not just looking whether the value \u003ccode\u003e3\u003c/code\u003e occurs or not -- instead, we want to find where it occurs \u003cem\u003efirst\u003c/em\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eSince this algorithm follows the same principle as binary search, we now ignore the right half of the array and calculate the new mid index:\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"[ 0, 1, 1, 3, 3, 3 | x, x, x, x, x, x ]\n *\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003e[ 0, 1, 1, 3, 3, 3 | x, x, x, x, x, x ]\n *\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAgain, we've landed on a \u003ccode\u003e3\u003c/code\u003e, and it's the very first one. But the algorithm doesn't know that, so we split the array again:\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"[ 0, 1, 1 | x, x, x | x, x, x, x, x, x ]\n *\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003e[ 0, 1, 1 | x, x, x | x, x, x, x, x, x ]\n *\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eStill not done. Split again, but this time use the right half:\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"[ x, x | 1 | x, x, x | x, x, x, x, x, x ]\n *\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003e[ x, x | 1 | x, x, x | x, x, x, x, x, x ]\n *\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe array cannot be split up any further, which means we've found the left boundary, at index 3.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eNow let's start over and try to find the right boundary. This is very similar, so I'll just show you the different steps:\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"[ 0, 1, 1, 3, 3, 3, 3, 6, 8, 10, 11, 11 ]\n *\n\n[ x, x, x, x, x, x, x | 6, 8, 10, 11, 11 ]\n *\n\n[ x, x, x, x, x, x, x | 6, 8, | x, x, x ]\n *\n\n[ x, x, x, x, x, x, x | 6 | x | x, x, x ]\n *\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003e[ 0, 1, 1, 3, 3, 3, 3, 6, 8, 10, 11, 11 ]\n *\n\n[ x, x, x, x, x, x, x | 6, 8, 10, 11, 11 ]\n *\n\n[ x, x, x, x, x, x, x | 6, 8, | x, x, x ]\n *\n\n[ x, x, x, x, x, x, x | 6 | x | x, x, x ]\n *\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe right boundary is at index 7. The difference between the two boundaries is 7 - 3 = 4, so the number \u003ccode\u003e3\u003c/code\u003e occurs four times in this array.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eEach binary search took 4 steps, so in total this algorithm took 8 steps. Not a big gain on an array of only 12 items, but the bigger the array, the more efficient this algorithm becomes. For a sorted array with 1,000,000 items, it only takes 2 x 20 = 40 steps to count the number of occurrences for any particular value.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eBy the way, if the value you're looking for is not in the array, then \u003ccode\u003erightBoundary\u003c/code\u003e and \u003ccode\u003eleftBoundary\u003c/code\u003e return the same value and so the difference between them is 0.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThis is an example of how you can modify the basic binary search to solve other algorithmic problems as well. Of course, it does require that the array is sorted.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cem\u003eWritten for Swift Algorithm Club by Matthijs Hollemans\u003c/em\u003e\u003c/p\u003e\n\u003c/article\u003e","errorMessage":null,"headerInfo":{"toc":[{"level":1,"text":"Count Occurrences","anchor":"count-occurrences","htmlText":"Count Occurrences"}],"siteNavLoginPath":"/login?return_to=https%3A%2F%2Fgithub.com%2Forchca%2Fswift-algorithm-club%2Ftree%2Fmaster%2FCount%2520Occurrences"}},"totalCount":3,"showBranchInfobar":true},"fileTree":{"":{"items":[{"name":".github","path":".github","contentType":"directory"},{"name":"3Sum and 4Sum","path":"3Sum and 4Sum","contentType":"directory"},{"name":"AVL Tree","path":"AVL Tree","contentType":"directory"},{"name":"All-Pairs Shortest Paths","path":"All-Pairs Shortest Paths","contentType":"directory"},{"name":"Array2D","path":"Array2D","contentType":"directory"},{"name":"B-Tree","path":"B-Tree","contentType":"directory"},{"name":"Binary Search Tree","path":"Binary Search Tree","contentType":"directory"},{"name":"Binary Search","path":"Binary Search","contentType":"directory"},{"name":"Binary Tree","path":"Binary Tree","contentType":"directory"},{"name":"Bit Set","path":"Bit Set","contentType":"directory"},{"name":"Bloom Filter","path":"Bloom Filter","contentType":"directory"},{"name":"Bounded Priority Queue","path":"Bounded Priority Queue","contentType":"directory"},{"name":"Boyer-Moore-Horspool","path":"Boyer-Moore-Horspool","contentType":"directory"},{"name":"Breadth-First Search","path":"Breadth-First Search","contentType":"directory"},{"name":"Brute-Force String Search","path":"Brute-Force String Search","contentType":"directory"},{"name":"Bubble Sort","path":"Bubble Sort","contentType":"directory"},{"name":"Bucket Sort","path":"Bucket Sort","contentType":"directory"},{"name":"Closest Pair","path":"Closest Pair","contentType":"directory"},{"name":"Comb Sort","path":"Comb Sort","contentType":"directory"},{"name":"Combinatorics","path":"Combinatorics","contentType":"directory"},{"name":"Convex Hull","path":"Convex Hull","contentType":"directory"},{"name":"Count Occurrences","path":"Count Occurrences","contentType":"directory"},{"name":"Counting Sort","path":"Counting Sort","contentType":"directory"},{"name":"Depth-First Search","path":"Depth-First Search","contentType":"directory"},{"name":"Deque","path":"Deque","contentType":"directory"},{"name":"Dijkstra Algorithm","path":"Dijkstra Algorithm","contentType":"directory"},{"name":"DiningPhilosophers","path":"DiningPhilosophers","contentType":"directory"},{"name":"Egg Drop Problem","path":"Egg Drop Problem","contentType":"directory"},{"name":"Encode and Decode Tree","path":"Encode and Decode Tree","contentType":"directory"},{"name":"Fixed Size Array","path":"Fixed Size Array","contentType":"directory"},{"name":"Fizz Buzz","path":"Fizz Buzz","contentType":"directory"},{"name":"GCD","path":"GCD","contentType":"directory"},{"name":"Genetic","path":"Genetic","contentType":"directory"},{"name":"Graph","path":"Graph","contentType":"directory"},{"name":"Hash Set","path":"Hash Set","contentType":"directory"},{"name":"Hash Table","path":"Hash Table","contentType":"directory"},{"name":"Hashed Heap","path":"Hashed Heap","contentType":"directory"},{"name":"HaversineDistance","path":"HaversineDistance","contentType":"directory"},{"name":"Heap Sort","path":"Heap Sort","contentType":"directory"},{"name":"Heap","path":"Heap","contentType":"directory"},{"name":"Huffman Coding","path":"Huffman Coding","contentType":"directory"},{"name":"Images","path":"Images","contentType":"directory"},{"name":"Insertion Sort","path":"Insertion Sort","contentType":"directory"},{"name":"Introsort","path":"Introsort","contentType":"directory"},{"name":"K-Means","path":"K-Means","contentType":"directory"},{"name":"Karatsuba Multiplication","path":"Karatsuba Multiplication","contentType":"directory"},{"name":"Knuth-Morris-Pratt","path":"Knuth-Morris-Pratt","contentType":"directory"},{"name":"Kth Largest Element","path":"Kth Largest Element","contentType":"directory"},{"name":"LRU Cache","path":"LRU Cache","contentType":"directory"},{"name":"Linear Regression","path":"Linear Regression","contentType":"directory"},{"name":"Linear Search","path":"Linear Search","contentType":"directory"},{"name":"Linked List","path":"Linked List","contentType":"directory"},{"name":"Longest Common Subsequence","path":"Longest Common Subsequence","contentType":"directory"},{"name":"Merge Sort","path":"Merge Sort","contentType":"directory"},{"name":"Miller-Rabin Primality Test","path":"Miller-Rabin Primality Test","contentType":"directory"},{"name":"Minimum Edit Distance","path":"Minimum Edit Distance","contentType":"directory"},{"name":"Minimum Spanning Tree (Unweighted)","path":"Minimum Spanning Tree (Unweighted)","contentType":"directory"},{"name":"Minimum Spanning Tree","path":"Minimum Spanning Tree","contentType":"directory"},{"name":"MinimumCoinChange","path":"MinimumCoinChange","contentType":"directory"},{"name":"Monty Hall Problem","path":"Monty Hall Problem","contentType":"directory"},{"name":"Multiset","path":"Multiset","contentType":"directory"},{"name":"Myers Difference Algorithm","path":"Myers Difference Algorithm","contentType":"directory"},{"name":"Naive Bayes Classifier","path":"Naive Bayes Classifier","contentType":"directory"},{"name":"Octree","path":"Octree","contentType":"directory"},{"name":"Ordered Array","path":"Ordered Array","contentType":"directory"},{"name":"Ordered Set","path":"Ordered Set","contentType":"directory"},{"name":"Palindromes","path":"Palindromes","contentType":"directory"},{"name":"Points Lines Planes","path":"Points Lines Planes","contentType":"directory"},{"name":"Priority Queue","path":"Priority Queue","contentType":"directory"},{"name":"QuadTree","path":"QuadTree","contentType":"directory"},{"name":"Queue","path":"Queue","contentType":"directory"},{"name":"Quicksort","path":"Quicksort","contentType":"directory"},{"name":"Rabin-Karp","path":"Rabin-Karp","contentType":"directory"},{"name":"Radix Sort","path":"Radix Sort","contentType":"directory"},{"name":"Radix Tree","path":"Radix Tree","contentType":"directory"},{"name":"Red-Black Tree","path":"Red-Black Tree","contentType":"directory"},{"name":"Ring Buffer","path":"Ring Buffer","contentType":"directory"},{"name":"Rootish Array Stack","path":"Rootish Array Stack","contentType":"directory"},{"name":"Run-Length Encoding","path":"Run-Length Encoding","contentType":"directory"},{"name":"Segment Tree","path":"Segment Tree","contentType":"directory"},{"name":"Select Minimum Maximum","path":"Select Minimum Maximum","contentType":"directory"},{"name":"Selection Sampling","path":"Selection Sampling","contentType":"directory"},{"name":"Selection Sort","path":"Selection Sort","contentType":"directory"},{"name":"Set Cover (Unweighted)","path":"Set Cover (Unweighted)","contentType":"directory"},{"name":"Shell Sort","path":"Shell Sort","contentType":"directory"},{"name":"Shortest Path (Unweighted)","path":"Shortest Path (Unweighted)","contentType":"directory"},{"name":"Shuffle","path":"Shuffle","contentType":"directory"},{"name":"Shunting Yard","path":"Shunting Yard","contentType":"directory"},{"name":"Simulated annealing","path":"Simulated annealing","contentType":"directory"},{"name":"Single-Source Shortest Paths (Weighted)","path":"Single-Source Shortest Paths (Weighted)","contentType":"directory"},{"name":"Singly Linked List","path":"Singly Linked List","contentType":"directory"},{"name":"Skip-List","path":"Skip-List","contentType":"directory"},{"name":"Slow Sort","path":"Slow Sort","contentType":"directory"},{"name":"Sorted Set","path":"Sorted Set","contentType":"directory"},{"name":"Sparse Table","path":"Sparse Table","contentType":"directory"},{"name":"Splay Tree","path":"Splay Tree","contentType":"directory"},{"name":"Stack","path":"Stack","contentType":"directory"},{"name":"Strassen Matrix Multiplication","path":"Strassen Matrix Multiplication","contentType":"directory"},{"name":"Ternary Search Tree","path":"Ternary Search Tree","contentType":"directory"},{"name":"Threaded Binary Tree","path":"Threaded Binary Tree","contentType":"directory"},{"name":"Topological Sort","path":"Topological Sort","contentType":"directory"},{"name":"Treap","path":"Treap","contentType":"directory"},{"name":"Tree","path":"Tree","contentType":"directory"},{"name":"Trie","path":"Trie","contentType":"directory"},{"name":"Two-Sum Problem","path":"Two-Sum Problem","contentType":"directory"},{"name":"Union-Find","path":"Union-Find","contentType":"directory"},{"name":"Z-Algorithm","path":"Z-Algorithm","contentType":"directory"},{"name":".gitignore","path":".gitignore","contentType":"file"},{"name":".swiftlint.yml","path":".swiftlint.yml","contentType":"file"},{"name":"Algorithm Design.markdown","path":"Algorithm Design.markdown","contentType":"file"},{"name":"Big-O Notation.markdown","path":"Big-O Notation.markdown","contentType":"file"},{"name":"LICENSE.txt","path":"LICENSE.txt","contentType":"file"},{"name":"README.markdown","path":"README.markdown","contentType":"file"},{"name":"Under Construction.markdown","path":"Under Construction.markdown","contentType":"file"},{"name":"What are Algorithms.markdown","path":"What are Algorithms.markdown","contentType":"file"},{"name":"Why Algorithms.markdown","path":"Why Algorithms.markdown","contentType":"file"},{"name":"gfm-render.sh","path":"gfm-render.sh","contentType":"file"},{"name":"install_swiftlint.sh","path":"install_swiftlint.sh","contentType":"file"}],"totalCount":118}},"fileTreeProcessingTime":5.6058959999999995,"foldersToFetch":[],"treeExpanded":true,"symbolsExpanded":false,"csrf_tokens":{"/orchca/swift-algorithm-club/branches":{"post":"9bnf4GhlGC7s0DvOE_iCon4g5gcOuivgqyJR4XYU9FpS7MLf747nImBeluGJyoATW4-w7rl2vwRueL42lau6ig"},"/orchca/swift-algorithm-club/branches/fetch_and_merge/master":{"post":"_wDDjo5wJZ669etNKErFGQKrL_o-YmNW2ja1pCAfav2g2-bDDRI7V1u5i_5gIzqYEqnCVnjARrF08AsE__fS0A"},"/orchca/swift-algorithm-club/branches/fetch_and_merge/master?discard_changes=true":{"post":"H0j_r31anIaNMz3QgXWqZxAEzc6WTaC9u2e-RfJZ6CdAk9ri_jiCT2x_XWPJHFXmAAYgYtDvhVoVoQDlLbFQCg"}}},"title":"swift-algorithm-club/Count Occurrences at master · orchca/swift-algorithm-club","appPayload":{"helpUrl":"https://docs.github.com","findFileWorkerPath":"/assets-cdn/worker/find-file-worker-263cab1760dd.js","findInFileWorkerPath":"/assets-cdn/worker/find-in-file-worker-1b17b3e7786a.js","githubDevUrl":null,"enabled_features":{"code_nav_ui_events":false,"react_blob_overlay":false,"accessible_code_button":true}}}