<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jonathan Tamsut</title>
    <description>The latest articles on DEV Community by Jonathan Tamsut (@jtamsut).</description>
    <link>https://dev.to/jtamsut</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F88976%2F036b186b-8696-4d79-af35-f19fd01b385e.jpg</url>
      <title>DEV Community: Jonathan Tamsut</title>
      <link>https://dev.to/jtamsut</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jtamsut"/>
    <language>en</language>
    <item>
      <title>An Intuitive Explanation of Big-O</title>
      <dc:creator>Jonathan Tamsut</dc:creator>
      <pubDate>Mon, 05 Nov 2018 17:33:15 +0000</pubDate>
      <link>https://dev.to/jtamsut/an-intuitive-explanation-of-big-o-52md</link>
      <guid>https://dev.to/jtamsut/an-intuitive-explanation-of-big-o-52md</guid>
      <description>

&lt;h1&gt;
  
  
  An Intuitive Explanation of Big-O
&lt;/h1&gt;

&lt;p&gt;In what follows is an intuitive (hopefully!) and concise discussion of big-O. I try to first explain what big-O is: &lt;em&gt;a way of estimating how long an algorithm will take to run to completion given the "worst" possible input&lt;/em&gt;. I then give a few examples of how to compute the big-O of an algorithm. All code samples are in JavaScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;An &lt;strong&gt;algorithm&lt;/strong&gt; is a list of instructions to complete some task. An example of an algorithm is a recipe. A &lt;strong&gt;data structure&lt;/strong&gt; is a way of organizing data. A family tree is a type of data structure. It organizes the relationships amongst familial relatives in an intuitive and hierarchical way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Big-O
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Big-O&lt;/strong&gt; is a measure of how long an algorithm takes to run to completion. Let's consider an example.&lt;/p&gt;

&lt;p&gt;The following algorithm, &lt;code&gt;isOneInArray&lt;/code&gt; takes an array of integers as input. It returns &lt;code&gt;true&lt;/code&gt; if a 1 &lt;em&gt;IS&lt;/em&gt; in the array and returns &lt;code&gt;false&lt;/code&gt; if the number 1 &lt;em&gt;IS NOT&lt;/em&gt; in the array. Remember that an integer is a number that can be written without a fractional component, like 4 or 1000.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isOneInArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;currentItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentItem&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Before we proceed any further let's construct a simple mental model of a CPU or Central Processing Unit. The CPU is what does "logical" computations on our computers. Our model of a CPU will ascribe the following properties to a CPU:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A CPU only does &lt;em&gt;comparisons&lt;/em&gt; that result in a Boolean (e.g., 1 !== 2 results in true); comparisons include &lt;code&gt;!==&lt;/code&gt;, &lt;code&gt;===&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;&lt;/code&gt;, etc. Our CPU compares at most &lt;em&gt;two&lt;/em&gt; values.&lt;/li&gt;
&lt;li&gt;A CPU can only do &lt;em&gt;ONE&lt;/em&gt; of these comparisons at a time.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This is a gross oversimplification of how a CPU actually works, but is close &lt;em&gt;enough&lt;/em&gt; for the purposes of this discussion.&lt;/p&gt;

&lt;p&gt;Let's consider a sample input for the &lt;code&gt;isOneInArray&lt;/code&gt; function:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;isOneInArray&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What is our CPU doing here?&lt;/p&gt;

&lt;p&gt;If we take a look at our implementation of the &lt;code&gt;isOneInArray&lt;/code&gt; function we can see that the CPU is being "asked" to compare each member in the array above. This is a total of 5 comparisons because there are 5 integers in the array. What the CPU is doing during the execution of the &lt;code&gt;isOneInArray&lt;/code&gt; function can be written as follows:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is 5 equal to 1? No. Next item in array.
Is 4 equal to 1? No. Next item in array.
Is 3 equal to 1? No. Next item in array.
Is 2 equal to 1? No. Next item in array.
Is 1 equal to 1? Yes. Return true!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;This was 5 comparisons&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is important to note that the number of comparisons equals the number of elements in the array. If we wanted to generalize we could say that the number of comparisons that our &lt;code&gt;isOneInArray&lt;/code&gt; function does is equal to &lt;strong&gt;N&lt;/strong&gt;, where &lt;strong&gt;N&lt;/strong&gt; is some positive integer that is equal to the length of the input array.&lt;/p&gt;

&lt;p&gt;Therefore we say &lt;code&gt;isOneInArray&lt;/code&gt; is &lt;em&gt;O(n)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;If we were to graph the number of comparisons done by our CPU against the length of an input array it would look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B0w5jtR8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://docs.google.com/drawings/d/1ERlK5scz4_dbylONq1caIGbSFfZ5AEQMP46alcLozuI/pub%3Fw%3D850%26h%3D541" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B0w5jtR8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://docs.google.com/drawings/d/1ERlK5scz4_dbylONq1caIGbSFfZ5AEQMP46alcLozuI/pub%3Fw%3D850%26h%3D541" alt="linear"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a linear line with a slope of 1. For this reason we say that our &lt;code&gt;isOneInArray&lt;/code&gt; algorithm is O(n) where n is the length of the input array. The only thing affects the number of comparisons our CPU does is the length of the input array.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One important thing to note is that whenever we are considering big-O we consider the worst possible input on an algorithm&lt;/strong&gt;. We can pretend that we have some evil genius adversary that is providing us with the input that would require us the most possible comparisons in our algorithm. A worst-case input for &lt;code&gt;isOneInArray&lt;/code&gt; would have the 1 at the very end of the array.&lt;/p&gt;

&lt;p&gt;We can also write functions that are O(n&lt;sup&gt;2&lt;/sup&gt;), O(nlogn) and O(constant). Remember the n&lt;sup&gt;2&lt;/sup&gt;, nlogn and constant are all just factors that we can multiply by an input array's length to get the number of comparisons an algorithm has to do.&lt;/p&gt;

&lt;p&gt;Let's consider an algorithm with a nested for-loop like this:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isTwoInArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nestedArray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;nestedArray&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;nestedArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nestedArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;How many comparisons will the above function make when given the following input:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;isTwoInArray&lt;/span&gt;&lt;span class="p"&gt;([[&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Generally speaking when determining big-O we can use the following expressions:&lt;/p&gt;

&lt;p&gt;O(n&lt;sup&gt;# of nest for-loops&lt;/sup&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This was an informal and not mathematically rigorous introduction to big-O. There are many more mathematically rigorous and in-depth resources on algorithms and asymptotic complexity. One of my favorites in &lt;a href="https://mitpress.mit.edu/books/introduction-algorithms-third-edition"&gt;&lt;em&gt;Introduction to Algorithms&lt;/em&gt; by C.L.R.S&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;


</description>
      <category>algorithms</category>
      <category>bigo</category>
    </item>
  </channel>
</rss>
